acts_as_markup 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -7,6 +7,7 @@ acts_as_markup.gemspec
7
7
  lib/acts/as_markup.rb
8
8
  lib/acts_as_markup.rb
9
9
  lib/acts_as_markup/exts/rdiscount.rb
10
+ lib/acts_as_markup/exts/string.rb
10
11
  tasks/bones.rake
11
12
  tasks/gem.rake
12
13
  tasks/git.rake
data/README.rdoc CHANGED
@@ -13,6 +13,11 @@ Allows you to specify columns of an ActiveRecord model that contain Markdown or
13
13
  Textile text. You may then use +to_s+ to get the original markdown or textile
14
14
  text or +to_html+ to get the formated HTML.
15
15
 
16
+ Additionally you can have a model that contains a column that has a column with
17
+ markup text, and another that defines what language to process it as. If the field
18
+ is listed as "markdown" or "textile" (case insensitive) it will treat it as such,
19
+ any other value for markup language will have the value pass through as a normal string.
20
+
16
21
  This AR extension can use 3 different types of Markdown processing backends:
17
22
  BlueCloth, RDiscount, or Ruby PEG. You specify which one you want to use by setting
18
23
  a config value in your environment.rb file:
@@ -32,6 +37,7 @@ By default RDiscount will be used.
32
37
  @post = Post.find(:first)
33
38
  @post.body.to_s #=> "## Markdown Headline"
34
39
  @post.body.to_html #=> "<h2> Markdown Headline</h2>"
40
+
35
41
 
36
42
  ==== Using +acts_as_textile+:
37
43
 
@@ -42,6 +48,7 @@ By default RDiscount will be used.
42
48
  @post = Post.find(:first)
43
49
  @post.body.to_s #=> "h2. Markdown Headline"
44
50
  @post.body.to_html #=> "<h2>Markdown Headline</h2>"
51
+
45
52
 
46
53
  ==== Using +acts_as_markup+:
47
54
 
@@ -52,6 +59,19 @@ By default RDiscount will be used.
52
59
  @post = Post.find(:first)
53
60
  @post.body.to_s #=> "## Markdown Headline"
54
61
  @post.body.to_html #=> "<h2> Markdown Headline</h2>"
62
+
63
+
64
+ ==== Using +acts_as_markup+ with +:variable+ language:
65
+
66
+ class Post < ActiveRecrod
67
+ acts_as_markup :language => :variable, :columns => [:body], :language_column => 'markup_language'
68
+ end
69
+
70
+ @post = Post.find(:first)
71
+ @post.markup_language # => "markdown"
72
+ @post.body.to_s # => "## Markdown Headline"
73
+ @post.body.to_html # => "<h2> Markdown Headline</h2>"
74
+
55
75
 
56
76
  == REQUIREMENTS:
57
77
 
@@ -1,14 +1,14 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{acts_as_markup}
3
- s.version = "0.1.1"
3
+ s.version = "0.2.0"
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
6
  s.authors = ["Brian Landau"]
7
- s.date = %q{2008-08-06}
7
+ s.date = %q{2008-08-07}
8
8
  s.description = %q{Represent ActiveRecord Markdown or Textile text columns as Markdown or Textile objects using various external libraries to convert to HTML.}
9
9
  s.email = %q{brian.landau@viget.com}
10
10
  s.extra_rdoc_files = ["LICENSE.txt", "README.rdoc"]
11
- s.files = ["History.txt", "LICENSE.txt", "Manifest.txt", "README.rdoc", "Rakefile", "acts_as_markup.gemspec", "lib/acts/as_markup.rb", "lib/acts_as_markup.rb", "lib/acts_as_markup/exts/rdiscount.rb", "tasks/bones.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/manifest.rake", "tasks/post_load.rake", "tasks/rdoc.rake", "tasks/rubyforge.rake", "tasks/setup.rb", "tasks/test.rake", "test/acts_as_markup_test.rb", "test/test_helper.rb"]
11
+ s.files = ["History.txt", "LICENSE.txt", "Manifest.txt", "README.rdoc", "Rakefile", "acts_as_markup.gemspec", "lib/acts/as_markup.rb", "lib/acts_as_markup.rb", "lib/acts_as_markup/exts/rdiscount.rb", "lib/acts_as_markup/exts/string.rb", "tasks/bones.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/manifest.rake", "tasks/post_load.rake", "tasks/rdoc.rake", "tasks/rubyforge.rake", "tasks/setup.rb", "tasks/test.rake", "test/acts_as_markup_test.rb", "test/test_helper.rb"]
12
12
  s.has_rdoc = true
13
13
  s.homepage = %q{http://viget.rubyforge.com/acts_as_markup}
14
14
  s.rdoc_options = ["--main", "README.rdoc"]
@@ -13,40 +13,98 @@ module ActiveRecord # :nodoc:
13
13
  # This allows you to specify columns you want to define as containing
14
14
  # Markdown or Textile content.
15
15
  # Then you can simply call <tt>.to_html</tt> method on the attribute.
16
- #
17
- # ==== Example
16
+ #
17
+ # You can also specify the language as <tt>:variable</tt> you will then
18
+ # need to add an additional option of <tt>:language_column</tt>. When
19
+ # a value is accessed it will create the correct object (Markdown or Textile)
20
+ # based on the value of the language column. If any value besides markdown or
21
+ # textile is supplied for the markup language the text will pass through
22
+ # as a string.
23
+ #
24
+ #
25
+ # ==== Examples
26
+ #
27
+ # ===== Using Markdown language
28
+ #
18
29
  # class Post < ActiveRecrod
19
30
  # acts_as_markup :language => :markdown, :columns => [:body]
20
31
  # end
32
+ #
33
+ # @post = Post.find(:first)
34
+ # @post.body.to_s # => "## Markdown Headline"
35
+ # @post.body.to_html # => "<h2> Markdown Headline</h2>"
36
+ #
21
37
  #
38
+ # ===== Using variable language
39
+ #
40
+ # class Post < ActiveRecrod
41
+ # acts_as_markup :language => :variable, :columns => [:body], :language_column => 'markup_language'
42
+ # end
43
+ #
22
44
  # @post = Post.find(:first)
23
- # @post.body.to_s #=> "## Markdown Headline"
24
- # @post.body.to_html #=> "<h2> Markdown Headline</h2>"
45
+ # @post.markup_language # => "markdown"
46
+ # @post.body.to_s # => "## Markdown Headline"
47
+ # @post.body.to_html # => "<h2> Markdown Headline</h2>"
48
+ #
25
49
  #
26
50
  def acts_as_markup(options)
27
51
  case options[:language].to_sym
28
52
  when :markdown
29
- library_names = ::ActsAsMarkup::MARKDOWN_LIBS[ActsAsMarkup.markdown_library]
30
- require library_names[:lib_name]
31
- klass = library_names[:class_name]
53
+ if ActsAsMarkup::MARKDOWN_LIBS.keys.include? ActsAsMarkup.markdown_library
54
+ markdown_library_names = ActsAsMarkup::MARKDOWN_LIBS[ActsAsMarkup.markdown_library]
55
+ require markdown_library_names[:lib_name]
56
+ klass = markdown_library_names[:class_name]
57
+ else
58
+ raise ActsAsMarkup::UnsportedMarkdownLibrary, "#{ActsAsMarkup.markdown_library} is not currently supported."
59
+ end
32
60
  when :textile
33
61
  require 'redcloth'
34
62
  klass = 'RedCloth'
63
+ when :variable
64
+ if ActsAsMarkup::MARKDOWN_LIBS.keys.include? ActsAsMarkup.markdown_library
65
+ markdown_library_names = ActsAsMarkup::MARKDOWN_LIBS[ActsAsMarkup.markdown_library]
66
+ require markdown_library_names[:lib_name]
67
+ markdown_klass = markdown_library_names[:class_name]
68
+ else
69
+ raise ActsAsMarkup::UnsportedMarkdownLibrary, "#{ActsAsMarkup.markdown_library} is not currently supported."
70
+ end
71
+ require 'redcloth'
72
+ textile_klass = 'RedCloth'
35
73
  else
36
74
  raise ActsAsMarkup::UnsportedMarkupLanguage, "#{options[:langauge]} is not a currently supported markup language."
37
75
  end
38
76
 
39
77
  options[:columns].each do |col|
40
- class_eval <<-EOV
41
- def #{col.to_s}
42
- if @#{col.to_s}
43
- if !self.#{col.to_s}_changed?
44
- return @#{col.to_s}
78
+ unless options[:language].to_sym == :variable
79
+ class_eval <<-EOV
80
+ def #{col.to_s}
81
+ if @#{col.to_s}
82
+ if !self.#{col.to_s}_changed?
83
+ return @#{col.to_s}
84
+ end
85
+ end
86
+ @#{col.to_s} = #{klass}.new(self['#{col.to_s}'].to_s)
87
+ end
88
+ EOV
89
+ else
90
+ class_eval <<-EOV
91
+ def #{col.to_s}
92
+ if @#{col.to_s}
93
+ unless self.#{col.to_s}_changed? || self.#{options[:language_column].to_s}_changed?
94
+ return @#{col.to_s}
95
+ end
96
+ end
97
+ case self.#{options[:language_column].to_s}
98
+ when /markdown/i
99
+ @#{col.to_s} = #{markdown_klass}.new(self['#{col.to_s}'].to_s)
100
+ when /textile/i
101
+ @#{col.to_s} = #{textile_klass}.new(self['#{col.to_s}'].to_s)
102
+ else
103
+ @#{col.to_s} = self['#{col.to_s}']
45
104
  end
46
105
  end
47
- @#{col.to_s} = #{klass}.new(self['#{col.to_s}'].to_s)
48
- end
49
- EOV
106
+ EOV
107
+ end
50
108
  end
51
109
  end
52
110
 
@@ -0,0 +1,9 @@
1
+ module ActsAsMarkup
2
+ module StringExtension
3
+ def to_html
4
+ self.to_s
5
+ end
6
+ end
7
+ end
8
+
9
+ String.send :include, ActsAsMarkup::StringExtension
@@ -2,7 +2,7 @@ require 'active_support'
2
2
 
3
3
  module ActsAsMarkup
4
4
  # :stopdoc:
5
- VERSION = '0.1.1'
5
+ VERSION = '0.2.0'
6
6
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
7
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
8
  # :startdoc:
@@ -11,6 +11,10 @@ module ActsAsMarkup
11
11
  class UnsportedMarkupLanguage < ArgumentError
12
12
  end
13
13
 
14
+ # This exception is raised when an unsupported Markdown library is set to the config value.
15
+ class UnsportedMarkdownLibrary < ArgumentError
16
+ end
17
+
14
18
  DEFAULT_MAKRDOWN_LIB = :rdiscount
15
19
 
16
20
  MARKDOWN_LIBS = { :rdiscount => {:class_name => "RDiscount",
data/tasks/git.rake CHANGED
@@ -34,7 +34,7 @@ namespace :git do
34
34
 
35
35
  end # namespace :git
36
36
 
37
- # task 'gem:release' => 'git:create_tag'
37
+ task 'gem:release' => 'git:create_tag'
38
38
 
39
39
  end # if HAVE_GIT
40
40
 
@@ -288,6 +288,270 @@ class ActsAsMarkupTest < Test::Unit::TestCase
288
288
  end
289
289
  end
290
290
 
291
+ context 'acts_as_markup with variable language' do
292
+ setup do
293
+ ActsAsMarkup.markdown_library = ActsAsMarkup::DEFAULT_MAKRDOWN_LIB
294
+ class ::VariablePost < ActiveRecord::Base
295
+ acts_as_markup :language => :variable, :columns => [:body], :language_column => :markup_language
296
+ end
297
+ end
298
+
299
+ context "with a Markdown post" do
300
+ setup do
301
+ @markdown_text = '## Markdown Test Text'
302
+ @markdown_post = VariablePost.create!(:title => 'Blah', :body => @markdown_text, :markup_language => 'Markdown')
303
+ end
304
+
305
+ should "have a markup object returned for the column value" do
306
+ assert_kind_of RDiscount, @markdown_post.body
307
+ end
308
+
309
+ should "return original markup text for a `to_s` method call on the column value" do
310
+ assert_equal @markdown_text, @markdown_post.body.to_s
311
+ end
312
+
313
+ should "return formated html for a `to_html` method call on the column value" do
314
+ assert_match(/<h2>\s*Markdown Test Text\s*<\/h2>/, @markdown_post.body.to_html)
315
+ end
316
+
317
+ context "changing value of markup field should return new markup object" do
318
+ setup do
319
+ @markdown_old_body = @markdown_post.body
320
+ @markdown_post.body = "`@count = 20`"
321
+ end
322
+
323
+ should "still have an markup object but not the same object" do
324
+ assert_not_same @markdown_post.body, @markdown_old_body
325
+ assert_kind_of RDiscount, @markdown_post.body
326
+ end
327
+
328
+ should "return correct text for `to_s`" do
329
+ assert_equal "`@count = 20`", @markdown_post.body.to_s
330
+ end
331
+
332
+ should "return correct HTML for the `to_html` method" do
333
+ assert_match(/<code>\s*\@count\s\=\s20\s*<\/code>/, @markdown_post.body.to_html)
334
+ end
335
+
336
+ teardown do
337
+ @markdown_old_body = nil
338
+ end
339
+ end
340
+
341
+ teardown do
342
+ @markdown_text, @markup_post = nil
343
+ end
344
+ end
345
+
346
+ context "with a Textile post" do
347
+ setup do
348
+ @textile_text = "h2. Textile Test Text"
349
+ @textile_post = VariablePost.create!(:title => 'Blah', :body => @textile_text, :markup_language => 'Textile')
350
+ end
351
+
352
+ should "have a markup object returned for the column value" do
353
+ assert_kind_of RedCloth::TextileDoc, @textile_post.body
354
+ end
355
+
356
+ should "return original markup text for a `to_s` method call on the column value" do
357
+ assert_equal @textile_text, @textile_post.body.to_s
358
+ end
359
+
360
+ should "return formated html for a `to_html` method call on the column value" do
361
+ assert_match(/<h2>Textile Test Text<\/h2>/, @textile_post.body.to_html)
362
+ end
363
+
364
+ context "changing value of markup field should return new markup object" do
365
+ setup do
366
+ @textile_old_body = @textile_post.body
367
+ @textile_post.body = "@@count = 20@"
368
+ end
369
+
370
+ should "still have an markup object but not the same object" do
371
+ assert_kind_of RedCloth::TextileDoc, @textile_post.body
372
+ assert_not_same @textile_post.body, @textile_old_body
373
+ end
374
+
375
+ should "return correct text for `to_s`" do
376
+ assert_equal "@@count = 20@", @textile_post.body.to_s
377
+ end
378
+
379
+ should "return correct HTML for the `to_html` method" do
380
+ assert_match(/<code>\@count\s\=\s20<\/code>/, @textile_post.body.to_html)
381
+ end
382
+
383
+ teardown do
384
+ @textile_old_body = nil
385
+ end
386
+ end
387
+
388
+ teardown do
389
+ @textile_text, @textile_post = nil
390
+ end
391
+ end
392
+
393
+ context "with a plain text post" do
394
+ setup do
395
+ @plain_text = "Hahaha!!!"
396
+ @plain_text_post = VariablePost.create!(:title => 'Blah', :body => @plain_text, :markup_language => 'text')
397
+ end
398
+
399
+ should "have a string object returned for the column value" do
400
+ assert_kind_of String, @plain_text_post.body
401
+ end
402
+
403
+ should "return the original string with a `to_s` method call on the column value" do
404
+ assert_equal @plain_text, @plain_text_post.body.to_s
405
+ end
406
+
407
+ should "eturn the original string with a `to_html` method call on the column value" do
408
+ assert_equal @plain_text, @plain_text_post.body.to_html
409
+ end
410
+
411
+ context "changing value of markup field should return new markup object" do
412
+ setup do
413
+ @plaintext_old_body = @plain_text_post.body
414
+ @plain_text_post.body = "Lorem ipsum dolor sit amet"
415
+ end
416
+
417
+ should "still have an markup object but not the same object" do
418
+ assert_kind_of String, @plain_text_post.body
419
+ assert_not_same @plain_text_post.body, @plaintext_old_body
420
+ end
421
+
422
+ should "return correct text for `to_s`" do
423
+ assert_equal "Lorem ipsum dolor sit amet", @plain_text_post.body.to_s
424
+ end
425
+
426
+ teardown do
427
+ @textile_old_body = nil
428
+ end
429
+ end
430
+
431
+ teardown do
432
+ @textile_text, @textile_post = nil
433
+ end
434
+ end
435
+
436
+
437
+ teardown do
438
+ VariablePost.delete_all
439
+ end
440
+ end
441
+
442
+ context 'with a nil value for the text' do
443
+ setup do
444
+ @text = nil
445
+ end
446
+
447
+ context 'with textile' do
448
+ setup do
449
+ class ::Post < ActiveRecord::Base
450
+ acts_as_textile :body
451
+ end
452
+ @post = Post.create!(:title => 'Blah', :body => @text)
453
+ end
454
+
455
+ should 'return a blank string for `to_s` method' do
456
+ assert_equal @post.body.to_s, ''
457
+ end
458
+
459
+ should 'return a blank string for `to_html` method' do
460
+ assert_match(/[\n\s]*/, @post.body.to_html)
461
+ end
462
+
463
+ should "have a RedCloth object returned for the column value" do
464
+ assert_kind_of RedCloth::TextileDoc, @post.body
465
+ end
466
+
467
+ teardown do
468
+ @post = nil
469
+ Post.delete_all
470
+ end
471
+ end
472
+
473
+ context 'with RDiscount Markdown' do
474
+ setup do
475
+ ActsAsMarkup.markdown_library = :rdiscount
476
+ class ::Post < ActiveRecord::Base
477
+ acts_as_markdown :body
478
+ end
479
+ @post = Post.create!(:title => 'Blah', :body => @text)
480
+ end
481
+
482
+ should 'return a blank string for `to_s` method' do
483
+ assert_equal @post.body.to_s, ''
484
+ end
485
+
486
+ should 'return a blank string for `to_html` method' do
487
+ assert_match(/[\n\s]*/, @post.body.to_html)
488
+ end
489
+
490
+ should "have a RDiscount object returned for the column value" do
491
+ assert_kind_of RDiscount, @post.body
492
+ end
493
+
494
+ teardown do
495
+ @post = nil
496
+ Post.delete_all
497
+ end
498
+ end
499
+
500
+ context 'with BlueCloth Markdown' do
501
+ setup do
502
+ ActsAsMarkup.markdown_library = :bluecloth
503
+ class ::Post < ActiveRecord::Base
504
+ acts_as_markdown :body
505
+ end
506
+ @post = Post.create!(:title => 'Blah', :body => @text)
507
+ end
508
+
509
+ should 'return a blank string for `to_s` method' do
510
+ assert_equal @post.body.to_s, ''
511
+ end
512
+
513
+ should 'return a blank string for `to_html` method' do
514
+ assert_match(/[\n\s]*/, @post.body.to_html)
515
+ end
516
+
517
+ should "have a BlueCloth object returned for the column value" do
518
+ assert_kind_of BlueCloth, @post.body
519
+ end
520
+
521
+ teardown do
522
+ @post = nil
523
+ Post.delete_all
524
+ end
525
+ end
526
+
527
+ context 'with Ruby PEG Markdown' do
528
+ setup do
529
+ ActsAsMarkup.markdown_library = :rpeg
530
+ class ::Post < ActiveRecord::Base
531
+ acts_as_markdown :body
532
+ end
533
+ @post = Post.create!(:title => 'Blah', :body => @text)
534
+ end
535
+
536
+ should 'return a blank string for `to_s` method' do
537
+ assert_equal @post.body.to_s, ''
538
+ end
539
+
540
+ should 'return a blank string for `to_html` method' do
541
+ assert_match(/[\n\s]*/, @post.body.to_html)
542
+ end
543
+
544
+ should "have a PEGMarkdown object returned for the column value" do
545
+ assert_kind_of PEGMarkdown, @post.body
546
+ end
547
+
548
+ teardown do
549
+ @post = nil
550
+ Post.delete_all
551
+ end
552
+ end
553
+ end
554
+
291
555
  context 'acts_as_markup with bad language name' do
292
556
  should 'raise exception when a non-supported language is passed to acts_as_markup' do
293
557
  assert_raise ActsAsMarkup::UnsportedMarkupLanguage do
data/test/test_helper.rb CHANGED
@@ -23,6 +23,13 @@ def setup_db
23
23
  t.column :body, :text
24
24
  t.timestamps
25
25
  end
26
+
27
+ create_table :variable_posts do |t|
28
+ t.column :title, :string
29
+ t.column :body, :text
30
+ t.column :markup_language, :string
31
+ t.timestamps
32
+ end
26
33
  end
27
34
  end
28
35
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_markup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Landau
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-06 00:00:00 -04:00
12
+ date: 2008-08-07 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -71,6 +71,7 @@ files:
71
71
  - lib/acts/as_markup.rb
72
72
  - lib/acts_as_markup.rb
73
73
  - lib/acts_as_markup/exts/rdiscount.rb
74
+ - lib/acts_as_markup/exts/string.rb
74
75
  - tasks/bones.rake
75
76
  - tasks/gem.rake
76
77
  - tasks/git.rake