├── .gitignore ├── .travis.yml ├── Appraisals ├── CHANGELOG ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.rdoc ├── Rakefile ├── acts_as_markup.gemspec ├── gemfiles ├── rails_30.gemfile ├── rails_30.gemfile.lock ├── rails_31.gemfile ├── rails_31.gemfile.lock ├── rails_32.gemfile ├── rails_32.gemfile.lock ├── rails_40.gemfile ├── rails_40.gemfile.lock ├── rails_41.gemfile ├── rails_41.gemfile.lock ├── rails_42.gemfile └── rails_42.gemfile.lock ├── lib ├── acts_as_markup.rb └── acts_as_markup │ ├── active_record_extension.rb │ ├── exts │ ├── bluecloth.rb │ ├── maruku.rb │ ├── peg_markdown.rb │ ├── rdiscount.rb │ ├── rdoc.rb │ ├── redcarpet.rb │ └── string.rb │ ├── railtie.rb │ ├── stringlike.rb │ └── version.rb ├── tasks ├── rdoc.rake └── test.rake └── test ├── acts_as_markdown_test.rb ├── acts_as_markup_test.rb ├── acts_as_rdoc_test.rb ├── acts_as_textile_test.rb └── test_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | doc 3 | pkg 4 | docs 5 | .rvmrc 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | sudo: false 3 | cache: bundler 4 | rvm: 5 | - "1.9.3" 6 | - "2.0.0" 7 | - "2.1.0" 8 | - "2.1.1" 9 | - "2.1.2" 10 | - "2.1.3" 11 | - "2.1.4" 12 | - "2.1.5" 13 | - "2.1.6" 14 | - "2.2.0" 15 | - "2.2.1" 16 | - "2.2.2" 17 | gemfile: 18 | - gemfiles/rails_30.gemfile 19 | - gemfiles/rails_31.gemfile 20 | - gemfiles/rails_32.gemfile 21 | - gemfiles/rails_40.gemfile 22 | - gemfiles/rails_41.gemfile 23 | - gemfiles/rails_42.gemfile 24 | matrix: 25 | exclude: 26 | - rvm: 2.2.0 27 | gemfile: gemfiles/rails_30.gemfile 28 | - rvm: 2.2.1 29 | gemfile: gemfiles/rails_30.gemfile 30 | - rvm: 2.2.2 31 | gemfile: gemfiles/rails_30.gemfile 32 | - rvm: 2.2.0 33 | gemfile: gemfiles/rails_31.gemfile 34 | - rvm: 2.2.1 35 | gemfile: gemfiles/rails_31.gemfile 36 | - rvm: 2.2.2 37 | gemfile: gemfiles/rails_31.gemfile 38 | - rvm: 2.2.0 39 | gemfile: gemfiles/rails_32.gemfile 40 | - rvm: 2.2.1 41 | gemfile: gemfiles/rails_32.gemfile 42 | - rvm: 2.2.2 43 | gemfile: gemfiles/rails_32.gemfile 44 | - rvm: 2.2.0 45 | gemfile: gemfiles/rails_40.gemfile 46 | - rvm: 2.2.1 47 | gemfile: gemfiles/rails_40.gemfile 48 | - rvm: 2.2.2 49 | gemfile: gemfiles/rails_40.gemfile 50 | notifications: 51 | slack: viget:g9nhMe2ZIu0p49xgfNQSfWxA 52 | -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | appraise "rails-30" do 2 | gem "activesupport", '~> 3.0.20' 3 | gem "activerecord", '~> 3.0.20' 4 | end 5 | 6 | appraise "rails-31" do 7 | gem "activesupport", '~> 3.1.12' 8 | gem "activerecord", '~> 3.1.12' 9 | end 10 | 11 | appraise "rails-32" do 12 | gem "activesupport", '~> 3.2.19' 13 | gem "activerecord", '~> 3.2.19' 14 | end 15 | 16 | appraise "rails-40" do 17 | gem "activesupport", '~> 4.0.9' 18 | gem "activerecord", '~> 4.0.9' 19 | end 20 | 21 | appraise "rails-41" do 22 | gem "activesupport", '~> 4.1.5' 23 | gem "activerecord", '~> 4.1.5' 24 | end 25 | 26 | appraise "rails-42" do 27 | gem "activesupport", '~> 4.2.3' 28 | gem "activerecord", '~> 4.2.3' 29 | end 30 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | == 2.0.2 / 2015-07-21 2 | * Plain text variable columns always return strings now 3 | * Refactor how we load markup classes to not load ones we aren't using. 4 | 5 | == 2.0.1 / 2014-09-04 6 | * Stop extending Object and extend string instead. 7 | 8 | == 2.0.0 / 2014-09-03 9 | * Update for latest version of Ruby & Rails 10 | 11 | == 1.4.2 / 2012-03-09 12 | * Bug fix 13 | 14 | == 1.4.1 / 2012-03-09 15 | * Bug fix 16 | 17 | == 1.4.0 / 2011-11-17 18 | * Make more like modern Rails 3 plugin. 19 | * Fix broken markup processors integration. 20 | * Refactor .acts_as_markup method 21 | * Allow use of different mediawiki libraries 22 | * Default mediawiki library is WikiCloth 23 | * Add support for Redcarpet markdown parser 24 | 25 | == 1.3.4 / 2010-09-04 26 | * Rails 3.x release 27 | 28 | == 1.3.3 / 2009-06-11 29 | * Maintenance release 30 | 31 | == 1.3.2 / 2009-04-28 32 | * Maintenance release 33 | 34 | == 1.3.1 / 2008-04-27 35 | * Update rake tasks and way RDoc is generated 36 | * Ensure works with Rails 2.3.2 and latest version of related markup gems. 37 | 38 | == 1.3.0 / 2008-11-19 39 | * Add ability to accept options that will be passed to supported markup parsers. (chewi[http://github.com/chewi/]) 40 | 41 | == 1.2.0 / 2008-09-10 42 | * Allow all objects to have a to_html method that defaults as to_s instead just doing this for strings. (idea from crnixon[http://github.com/crnixon/]) 43 | * Add string methods to all markup objects via the StringLike mixin. (crnixon[http://github.com/crnixon/]) 44 | * Other Minor bug fixes 45 | 46 | == 1.1.2 / 2008-08-22 47 | * Make sure all markup objects properly respond to the .blank? method call. 48 | 49 | == 1.1.0 / 2008-08-12 50 | 51 | * Use a default for markup language column name when the variable options is used. 52 | 53 | == 1.0.0 / 2008-08-11 54 | 55 | * Add support for Maruku Markdown Library. 56 | 57 | == 0.4.0 / 2008-08-11 58 | 59 | * Add support for RDoc. 60 | 61 | == 0.3.0 / 2008-08-08 62 | 63 | * Add support for wikitext. 64 | 65 | == 0.2.0 / 2008-08-07 66 | 67 | * Add support for a variable markup language option. 68 | 69 | == 0.1.0 / 2008-08-05 70 | 71 | * Initial Release 72 | * Support for Markdown and Textile markup languages. 73 | * `acts_as_markdown` and `acts_as_textile` convenience methods 74 | * Support for BlueCloth, RDiscount and Ruby PEG markdown processors. 75 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | acts_as_markup (2.0.2) 5 | activerecord (>= 3.0.20) 6 | activesupport (>= 3.0.20) 7 | rdiscount 8 | 9 | GEM 10 | remote: http://rubygems.org/ 11 | specs: 12 | RedCloth (4.2.9) 13 | activemodel (4.2.3) 14 | activesupport (= 4.2.3) 15 | builder (~> 3.1) 16 | activerecord (4.2.3) 17 | activemodel (= 4.2.3) 18 | activesupport (= 4.2.3) 19 | arel (~> 6.0) 20 | activesupport (4.2.3) 21 | i18n (~> 0.7) 22 | json (~> 1.7, >= 1.7.7) 23 | minitest (~> 5.1) 24 | thread_safe (~> 0.3, >= 0.3.4) 25 | tzinfo (~> 1.1) 26 | appraisal (2.0.2) 27 | bundler 28 | rake 29 | thor (>= 0.14.0) 30 | arel (6.0.2) 31 | bluecloth (2.2.0) 32 | brianjlandau-sdoc-helpers (0.1.5) 33 | builder (3.2.2) 34 | i18n (0.7.0) 35 | json (1.8.3) 36 | maruku (0.7.2) 37 | minitest (5.7.0) 38 | rake (10.4.2) 39 | rdiscount (2.1.8) 40 | rdoc (4.2.0) 41 | redcarpet (3.3.2) 42 | rpeg-markdown (1.4.6) 43 | sdoc (0.4.1) 44 | json (~> 1.7, >= 1.7.7) 45 | rdoc (~> 4.0) 46 | shoulda (3.5.0) 47 | shoulda-context (~> 1.0, >= 1.0.1) 48 | shoulda-matchers (>= 1.4.1, < 3.0) 49 | shoulda-context (1.2.1) 50 | shoulda-matchers (2.8.0) 51 | activesupport (>= 3.0.0) 52 | sqlite3 (1.3.10) 53 | thor (0.19.1) 54 | thread_safe (0.3.5) 55 | tzinfo (1.2.2) 56 | thread_safe (~> 0.1) 57 | 58 | PLATFORMS 59 | ruby 60 | 61 | DEPENDENCIES 62 | RedCloth 63 | acts_as_markup! 64 | appraisal 65 | bluecloth 66 | brianjlandau-sdoc-helpers 67 | maruku 68 | rdoc (~> 4.0) 69 | redcarpet 70 | rpeg-markdown 71 | sdoc 72 | shoulda 73 | sqlite3 74 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2008 Brian Landau of Viget Labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = Acts as Markup 2 | 3 | {}[https://codeclimate.com/github/vigetlabs/acts_as_markup] {}[https://travis-ci.org/vigetlabs/acts_as_markup] {}[http://badge.fury.io/rb/acts_as_markup] 4 | 5 | by Brian Landau of Viget Labs 6 | 7 | GitHub Project: http://github.com/vigetlabs/acts_as_markup 8 | 9 | RDoc: 10 | * http://gitrdoc.com/vigetlabs/acts_as_markup/tree/master 11 | * http://vigetlabs.github.com/acts_as_markup 12 | 13 | 14 | == DESCRIPTION: 15 | 16 | Allows you to specify columns of an ActiveRecord model that contain Markdown, 17 | Textile, and RDoc. You may then use +to_s+ to get the original markup 18 | text or +to_html+ to get the formated HTML. 19 | 20 | Additionally you can have a model that contains a column that has a column with 21 | markup text, and another that defines what language to process it as. If the field 22 | is listed as "markdown" "textile", or "rdoc" (case insensitive) it will 23 | treat it as such, any other value for markup language will have the value pass 24 | through as a normal string. 25 | 26 | This AR extension can use 5 different types of Markdown processing backends: 27 | BlueCloth, RDiscount, Ruby PEG, Redcarpet or Maruku. You specify which one you want to use by setting 28 | a config value in your environment.rb file: 29 | 30 | ActsAsMarkup.markdown_library = :bluecloth 31 | 32 | By default RDiscount will be used. 33 | 34 | You can specify additional options to pass to the markup library by using 35 | :markdown_options, :textile_options. 36 | RDoc does not support any useful options. The options should be given as an 37 | array of arguments. You can specify options for multiple languages when 38 | allowing more than one. See each library's documentation for more details on 39 | what options are available. 40 | 41 | == EXAMPLES: 42 | 43 | ==== Using +acts_as_markdown+: 44 | 45 | class Post < ActiveRecord 46 | acts_as_markdown :body 47 | end 48 | 49 | @post = Post.find(:first) 50 | @post.body.to_s #=> "## Markdown Headline" 51 | @post.body.to_html #=> "

Markdown Headline

" 52 | 53 | 54 | ==== Using +acts_as_textile+: 55 | 56 | class Post < ActiveRecord 57 | acts_as_textile :body 58 | end 59 | 60 | @post = Post.find(:first) 61 | @post.body.to_s #=> "h2. Textile Headline" 62 | @post.body.to_html #=> "

Textile Headline

" 63 | 64 | 65 | ==== Using +acts_as_rdoc+: 66 | 67 | class Post < ActiveRecord 68 | acts_as_rdoc :body 69 | end 70 | 71 | @post = Post.find(:first) 72 | @post.body.to_s #=> "== RDoc Headline" 73 | @post.body.to_html #=> "

RDoc Headline

" 74 | 75 | 76 | ==== Using +acts_as_markup+: 77 | 78 | class Post < ActiveRecord 79 | acts_as_markup :language => :markdown, :columns => [:body] 80 | end 81 | 82 | @post = Post.find(:first) 83 | @post.body.to_s #=> "## Markdown Headline" 84 | @post.body.to_html #=> "

Markdown Headline

" 85 | 86 | 87 | ==== Using +acts_as_markup+ with :variable language: 88 | 89 | class Post < ActiveRecord 90 | acts_as_markup :language => :variable, :columns => [:body] 91 | end 92 | 93 | @post = Post.find(:first) 94 | @post.markup_language # => "markdown" 95 | @post.body.to_s # => "## Markdown Headline" 96 | @post.body.to_html # => "

Markdown Headline

" 97 | 98 | 99 | ==== Using options 100 | 101 | class Post < ActiveRecord 102 | acts_as_markdown :body, :markdown_options => [ :filter_html ] 103 | end 104 | 105 | class Post < ActiveRecord 106 | acts_as_textile :body, :textile_options => [ [ :filter_html ] ] 107 | end 108 | 109 | 110 | == REQUIREMENTS: 111 | 112 | You will need the RedCloth[http://whytheluckystiff.net/ruby/redcloth/] library 113 | for processing the Textile text. 114 | 115 | You will also need to install some type of Markdown processor. 116 | The four options currently supported are: 117 | 118 | * BlueCloth 119 | * RDiscount[http://github.com/rtomayko/rdiscount] 120 | * {Ruby PEG}[http://github.com/rtomayko/rpeg-markdown] 121 | * Maruku[http://maruku.rubyforge.org/] 122 | * Redcarpet[https://github.com/tanoku/redcarpet] 123 | 124 | == INSTALL: 125 | 126 | Simply add "+acts_as_markup+" to your Gemfile: 127 | 128 | gem "acts_as_markup" 129 | 130 | And run "+bundle+ +install+" 131 | 132 | == CONTRIBUTING: 133 | 134 | Make a fork on GitHub, make your changes and do a pull request. Good places to start are adding new Markdown libraries or new markup languages, here's instructions for both: 135 | 136 | === Instructions for how to add a new Markdown Library: 137 | 138 | 1. Add another item to the ActsAsMarkup::MARKDOWN_LIBS hash in the form of: 139 | :bluecloth => {:class_name => "BlueCloth", 140 | :lib_name => "bluecloth"} 141 | :lib_name should be the name needed to require the library, while :class_name should be the class that we are making an instance of. 142 | 2. If you need to modify the object in anyway (e.g. to add a to_s or to_html method), add a file to the "lib/acts_as_markup/exts/" directory. 143 | 3. Add appropriate tests (see current tests). 144 | 145 | === Instructions for how to add a new Markup Language: 146 | 147 | 1. Add a "when" statement to the "case" statement in acts_as_markup. The "when" statement should match with a symbol that represents the language name in some way (e.g. ":markdown"). 148 | 2. In the "when" block you need to set the "klass" local variable and require the library and the extension file if you need one (use the special require_extensions method to require extensions). 149 | 3. Add the same lines you added to the previous "when" statement to the ":variable" "when" statement. But replace "klass" with "language_klass" (e.g. "markdown_klass"). 150 | 4. Add a relevant "when" statement to the class_eval block for the ":variable" language option. This should look something like: 151 | when /markdown/i 152 | markup_klasses[:markdown].new self[col].to_s 153 | 5. Add a convenience method (e.g. "acts_as_markdown") 154 | 6. Add an extension file to the "lib/acts_as_markup/exts/" directory if you need to modify the object in anyway. 155 | 7. Add appropriate tests (see current tests). 156 | 157 | --- 158 | 159 | {Code At Viget}[http://code.viget.com] 160 | 161 | Visit {code.viget.com}[http://code.viget.com] to see more projects from {Viget.}[https://viget.com] 162 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | begin 3 | require 'bundler/setup' 4 | require 'appraisal' 5 | rescue LoadError 6 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks' 7 | end 8 | 9 | Bundler::GemHelper.install_tasks 10 | 11 | Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f } 12 | 13 | task :default => :test 14 | -------------------------------------------------------------------------------- /acts_as_markup.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", __FILE__) 2 | 3 | require "acts_as_markup/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "acts_as_markup" 7 | s.version = ActsAsMarkup::VERSION 8 | 9 | s.authors = ["Brian Landau"] 10 | s.description = "Represent ActiveRecord Markdown, Textile, RDoc columns as Markdown, Textile, RDoc objects using various external libraries to convert to HTML." 11 | s.email = "brian.landau@viget.com" 12 | s.extra_rdoc_files = [ 13 | "LICENSE", 14 | "CHANGELOG", 15 | "README.rdoc" 16 | ] 17 | s.files = Dir["{app,config,db,lib}/**/*"] + ["LICENSE", "Rakefile", "README.rdoc", "CHANGELOG"] 18 | s.test_files = Dir["test/**/*"] 19 | 20 | s.homepage = "http://vigetlabs.github.com/acts_as_markup/" 21 | s.license = "MIT" 22 | s.require_paths = ["lib"] 23 | s.summary = "Represent ActiveRecord Markdown, Textile, RDoc columns as Markdown, Textile, RDoc objects using various external libraries to convert to HTML." 24 | 25 | s.add_dependency "activesupport", '>= 3.0.20' 26 | s.add_dependency "activerecord", '>= 3.0.20' 27 | s.add_dependency "rdiscount" 28 | 29 | s.add_development_dependency "appraisal" 30 | s.add_development_dependency "sqlite3" 31 | s.add_development_dependency "shoulda" 32 | s.add_development_dependency "sdoc" 33 | s.add_development_dependency "brianjlandau-sdoc-helpers" 34 | s.add_development_dependency "RedCloth" 35 | s.add_development_dependency "rdoc", '~> 4.0' 36 | s.add_development_dependency "bluecloth" 37 | s.add_development_dependency "maruku" 38 | s.add_development_dependency "rpeg-markdown" 39 | s.add_development_dependency "redcarpet" 40 | end 41 | 42 | -------------------------------------------------------------------------------- /gemfiles/rails_30.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "activesupport", "~> 3.0.20" 6 | gem "activerecord", "~> 3.0.20" 7 | 8 | gemspec :path => "../" 9 | -------------------------------------------------------------------------------- /gemfiles/rails_30.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | acts_as_markup (2.0.2) 5 | activerecord (>= 3.0.20) 6 | activesupport (>= 3.0.20) 7 | rdiscount 8 | 9 | GEM 10 | remote: http://rubygems.org/ 11 | specs: 12 | RedCloth (4.2.9) 13 | activemodel (3.0.20) 14 | activesupport (= 3.0.20) 15 | builder (~> 2.1.2) 16 | i18n (~> 0.5.0) 17 | activerecord (3.0.20) 18 | activemodel (= 3.0.20) 19 | activesupport (= 3.0.20) 20 | arel (~> 2.0.10) 21 | tzinfo (~> 0.3.23) 22 | activesupport (3.0.20) 23 | appraisal (2.0.2) 24 | bundler 25 | rake 26 | thor (>= 0.14.0) 27 | arel (2.0.10) 28 | bluecloth (2.2.0) 29 | brianjlandau-sdoc-helpers (0.1.5) 30 | builder (2.1.2) 31 | i18n (0.5.4) 32 | json (1.8.3) 33 | maruku (0.7.2) 34 | rake (10.4.2) 35 | rdiscount (2.1.8) 36 | rdoc (4.2.0) 37 | redcarpet (3.3.2) 38 | rpeg-markdown (1.4.6) 39 | sdoc (0.4.1) 40 | json (~> 1.7, >= 1.7.7) 41 | rdoc (~> 4.0) 42 | shoulda (3.5.0) 43 | shoulda-context (~> 1.0, >= 1.0.1) 44 | shoulda-matchers (>= 1.4.1, < 3.0) 45 | shoulda-context (1.2.1) 46 | shoulda-matchers (2.8.0) 47 | activesupport (>= 3.0.0) 48 | sqlite3 (1.3.10) 49 | thor (0.19.1) 50 | tzinfo (0.3.44) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | RedCloth 57 | activerecord (~> 3.0.20) 58 | activesupport (~> 3.0.20) 59 | acts_as_markup! 60 | appraisal 61 | bluecloth 62 | brianjlandau-sdoc-helpers 63 | maruku 64 | rdoc (~> 4.0) 65 | redcarpet 66 | rpeg-markdown 67 | sdoc 68 | shoulda 69 | sqlite3 70 | -------------------------------------------------------------------------------- /gemfiles/rails_31.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "activesupport", "~> 3.1.12" 6 | gem "activerecord", "~> 3.1.12" 7 | 8 | gemspec :path => "../" 9 | -------------------------------------------------------------------------------- /gemfiles/rails_31.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | acts_as_markup (2.0.2) 5 | activerecord (>= 3.0.20) 6 | activesupport (>= 3.0.20) 7 | rdiscount 8 | 9 | GEM 10 | remote: http://rubygems.org/ 11 | specs: 12 | RedCloth (4.2.9) 13 | activemodel (3.1.12) 14 | activesupport (= 3.1.12) 15 | builder (~> 3.0.0) 16 | i18n (~> 0.6) 17 | activerecord (3.1.12) 18 | activemodel (= 3.1.12) 19 | activesupport (= 3.1.12) 20 | arel (~> 2.2.3) 21 | tzinfo (~> 0.3.29) 22 | activesupport (3.1.12) 23 | multi_json (~> 1.0) 24 | appraisal (2.0.2) 25 | bundler 26 | rake 27 | thor (>= 0.14.0) 28 | arel (2.2.3) 29 | bluecloth (2.2.0) 30 | brianjlandau-sdoc-helpers (0.1.5) 31 | builder (3.0.4) 32 | i18n (0.7.0) 33 | json (1.8.3) 34 | maruku (0.7.2) 35 | multi_json (1.11.2) 36 | rake (10.4.2) 37 | rdiscount (2.1.8) 38 | rdoc (4.2.0) 39 | redcarpet (3.3.2) 40 | rpeg-markdown (1.4.6) 41 | sdoc (0.4.1) 42 | json (~> 1.7, >= 1.7.7) 43 | rdoc (~> 4.0) 44 | shoulda (3.5.0) 45 | shoulda-context (~> 1.0, >= 1.0.1) 46 | shoulda-matchers (>= 1.4.1, < 3.0) 47 | shoulda-context (1.2.1) 48 | shoulda-matchers (2.8.0) 49 | activesupport (>= 3.0.0) 50 | sqlite3 (1.3.10) 51 | thor (0.19.1) 52 | tzinfo (0.3.44) 53 | 54 | PLATFORMS 55 | ruby 56 | 57 | DEPENDENCIES 58 | RedCloth 59 | activerecord (~> 3.1.12) 60 | activesupport (~> 3.1.12) 61 | acts_as_markup! 62 | appraisal 63 | bluecloth 64 | brianjlandau-sdoc-helpers 65 | maruku 66 | rdoc (~> 4.0) 67 | redcarpet 68 | rpeg-markdown 69 | sdoc 70 | shoulda 71 | sqlite3 72 | -------------------------------------------------------------------------------- /gemfiles/rails_32.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "activesupport", "~> 3.2.19" 6 | gem "activerecord", "~> 3.2.19" 7 | 8 | gemspec :path => "../" 9 | -------------------------------------------------------------------------------- /gemfiles/rails_32.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | acts_as_markup (2.0.2) 5 | activerecord (>= 3.0.20) 6 | activesupport (>= 3.0.20) 7 | rdiscount 8 | 9 | GEM 10 | remote: http://rubygems.org/ 11 | specs: 12 | RedCloth (4.2.9) 13 | activemodel (3.2.22) 14 | activesupport (= 3.2.22) 15 | builder (~> 3.0.0) 16 | activerecord (3.2.22) 17 | activemodel (= 3.2.22) 18 | activesupport (= 3.2.22) 19 | arel (~> 3.0.2) 20 | tzinfo (~> 0.3.29) 21 | activesupport (3.2.22) 22 | i18n (~> 0.6, >= 0.6.4) 23 | multi_json (~> 1.0) 24 | appraisal (2.0.2) 25 | bundler 26 | rake 27 | thor (>= 0.14.0) 28 | arel (3.0.3) 29 | bluecloth (2.2.0) 30 | brianjlandau-sdoc-helpers (0.1.5) 31 | builder (3.0.4) 32 | i18n (0.7.0) 33 | json (1.8.3) 34 | maruku (0.7.2) 35 | multi_json (1.11.2) 36 | rake (10.4.2) 37 | rdiscount (2.1.8) 38 | rdoc (4.2.0) 39 | redcarpet (3.3.2) 40 | rpeg-markdown (1.4.6) 41 | sdoc (0.4.1) 42 | json (~> 1.7, >= 1.7.7) 43 | rdoc (~> 4.0) 44 | shoulda (3.5.0) 45 | shoulda-context (~> 1.0, >= 1.0.1) 46 | shoulda-matchers (>= 1.4.1, < 3.0) 47 | shoulda-context (1.2.1) 48 | shoulda-matchers (2.8.0) 49 | activesupport (>= 3.0.0) 50 | sqlite3 (1.3.10) 51 | thor (0.19.1) 52 | tzinfo (0.3.44) 53 | 54 | PLATFORMS 55 | ruby 56 | 57 | DEPENDENCIES 58 | RedCloth 59 | activerecord (~> 3.2.19) 60 | activesupport (~> 3.2.19) 61 | acts_as_markup! 62 | appraisal 63 | bluecloth 64 | brianjlandau-sdoc-helpers 65 | maruku 66 | rdoc (~> 4.0) 67 | redcarpet 68 | rpeg-markdown 69 | sdoc 70 | shoulda 71 | sqlite3 72 | -------------------------------------------------------------------------------- /gemfiles/rails_40.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "activesupport", "~> 4.0.9" 6 | gem "activerecord", "~> 4.0.9" 7 | 8 | gemspec :path => "../" 9 | -------------------------------------------------------------------------------- /gemfiles/rails_40.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | acts_as_markup (2.0.2) 5 | activerecord (>= 3.0.20) 6 | activesupport (>= 3.0.20) 7 | rdiscount 8 | 9 | GEM 10 | remote: http://rubygems.org/ 11 | specs: 12 | RedCloth (4.2.9) 13 | activemodel (4.0.13) 14 | activesupport (= 4.0.13) 15 | builder (~> 3.1.0) 16 | activerecord (4.0.13) 17 | activemodel (= 4.0.13) 18 | activerecord-deprecated_finders (~> 1.0.2) 19 | activesupport (= 4.0.13) 20 | arel (~> 4.0.0) 21 | activerecord-deprecated_finders (1.0.4) 22 | activesupport (4.0.13) 23 | i18n (~> 0.6, >= 0.6.9) 24 | minitest (~> 4.2) 25 | multi_json (~> 1.3) 26 | thread_safe (~> 0.1) 27 | tzinfo (~> 0.3.37) 28 | appraisal (2.0.2) 29 | bundler 30 | rake 31 | thor (>= 0.14.0) 32 | arel (4.0.2) 33 | bluecloth (2.2.0) 34 | brianjlandau-sdoc-helpers (0.1.5) 35 | builder (3.1.4) 36 | i18n (0.7.0) 37 | json (1.8.3) 38 | maruku (0.7.2) 39 | minitest (4.7.5) 40 | multi_json (1.11.2) 41 | rake (10.4.2) 42 | rdiscount (2.1.8) 43 | rdoc (4.2.0) 44 | redcarpet (3.3.2) 45 | rpeg-markdown (1.4.6) 46 | sdoc (0.4.1) 47 | json (~> 1.7, >= 1.7.7) 48 | rdoc (~> 4.0) 49 | shoulda (3.5.0) 50 | shoulda-context (~> 1.0, >= 1.0.1) 51 | shoulda-matchers (>= 1.4.1, < 3.0) 52 | shoulda-context (1.2.1) 53 | shoulda-matchers (2.8.0) 54 | activesupport (>= 3.0.0) 55 | sqlite3 (1.3.10) 56 | thor (0.19.1) 57 | thread_safe (0.3.5) 58 | tzinfo (0.3.44) 59 | 60 | PLATFORMS 61 | ruby 62 | 63 | DEPENDENCIES 64 | RedCloth 65 | activerecord (~> 4.0.9) 66 | activesupport (~> 4.0.9) 67 | acts_as_markup! 68 | appraisal 69 | bluecloth 70 | brianjlandau-sdoc-helpers 71 | maruku 72 | rdoc (~> 4.0) 73 | redcarpet 74 | rpeg-markdown 75 | sdoc 76 | shoulda 77 | sqlite3 78 | -------------------------------------------------------------------------------- /gemfiles/rails_41.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "activesupport", "~> 4.1.5" 6 | gem "activerecord", "~> 4.1.5" 7 | 8 | gemspec :path => "../" 9 | -------------------------------------------------------------------------------- /gemfiles/rails_41.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | acts_as_markup (2.0.2) 5 | activerecord (>= 3.0.20) 6 | activesupport (>= 3.0.20) 7 | rdiscount 8 | 9 | GEM 10 | remote: http://rubygems.org/ 11 | specs: 12 | RedCloth (4.2.9) 13 | activemodel (4.1.12) 14 | activesupport (= 4.1.12) 15 | builder (~> 3.1) 16 | activerecord (4.1.12) 17 | activemodel (= 4.1.12) 18 | activesupport (= 4.1.12) 19 | arel (~> 5.0.0) 20 | activesupport (4.1.12) 21 | i18n (~> 0.6, >= 0.6.9) 22 | json (~> 1.7, >= 1.7.7) 23 | minitest (~> 5.1) 24 | thread_safe (~> 0.1) 25 | tzinfo (~> 1.1) 26 | appraisal (2.0.2) 27 | bundler 28 | rake 29 | thor (>= 0.14.0) 30 | arel (5.0.1.20140414130214) 31 | bluecloth (2.2.0) 32 | brianjlandau-sdoc-helpers (0.1.5) 33 | builder (3.2.2) 34 | i18n (0.7.0) 35 | json (1.8.3) 36 | maruku (0.7.2) 37 | minitest (5.7.0) 38 | rake (10.4.2) 39 | rdiscount (2.1.8) 40 | rdoc (4.2.0) 41 | redcarpet (3.3.2) 42 | rpeg-markdown (1.4.6) 43 | sdoc (0.4.1) 44 | json (~> 1.7, >= 1.7.7) 45 | rdoc (~> 4.0) 46 | shoulda (3.5.0) 47 | shoulda-context (~> 1.0, >= 1.0.1) 48 | shoulda-matchers (>= 1.4.1, < 3.0) 49 | shoulda-context (1.2.1) 50 | shoulda-matchers (2.8.0) 51 | activesupport (>= 3.0.0) 52 | sqlite3 (1.3.10) 53 | thor (0.19.1) 54 | thread_safe (0.3.5) 55 | tzinfo (1.2.2) 56 | thread_safe (~> 0.1) 57 | 58 | PLATFORMS 59 | ruby 60 | 61 | DEPENDENCIES 62 | RedCloth 63 | activerecord (~> 4.1.5) 64 | activesupport (~> 4.1.5) 65 | acts_as_markup! 66 | appraisal 67 | bluecloth 68 | brianjlandau-sdoc-helpers 69 | maruku 70 | rdoc (~> 4.0) 71 | redcarpet 72 | rpeg-markdown 73 | sdoc 74 | shoulda 75 | sqlite3 76 | -------------------------------------------------------------------------------- /gemfiles/rails_42.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "activesupport", "~> 4.2.3" 6 | gem "activerecord", "~> 4.2.3" 7 | 8 | gemspec :path => "../" 9 | -------------------------------------------------------------------------------- /gemfiles/rails_42.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | acts_as_markup (2.0.2) 5 | activerecord (>= 3.0.20) 6 | activesupport (>= 3.0.20) 7 | rdiscount 8 | 9 | GEM 10 | remote: http://rubygems.org/ 11 | specs: 12 | RedCloth (4.2.9) 13 | activemodel (4.2.3) 14 | activesupport (= 4.2.3) 15 | builder (~> 3.1) 16 | activerecord (4.2.3) 17 | activemodel (= 4.2.3) 18 | activesupport (= 4.2.3) 19 | arel (~> 6.0) 20 | activesupport (4.2.3) 21 | i18n (~> 0.7) 22 | json (~> 1.7, >= 1.7.7) 23 | minitest (~> 5.1) 24 | thread_safe (~> 0.3, >= 0.3.4) 25 | tzinfo (~> 1.1) 26 | appraisal (2.0.2) 27 | bundler 28 | rake 29 | thor (>= 0.14.0) 30 | arel (6.0.2) 31 | bluecloth (2.2.0) 32 | brianjlandau-sdoc-helpers (0.1.5) 33 | builder (3.2.2) 34 | i18n (0.7.0) 35 | json (1.8.3) 36 | maruku (0.7.2) 37 | minitest (5.7.0) 38 | rake (10.4.2) 39 | rdiscount (2.1.8) 40 | rdoc (4.2.0) 41 | redcarpet (3.3.2) 42 | rpeg-markdown (1.4.6) 43 | sdoc (0.4.1) 44 | json (~> 1.7, >= 1.7.7) 45 | rdoc (~> 4.0) 46 | shoulda (3.5.0) 47 | shoulda-context (~> 1.0, >= 1.0.1) 48 | shoulda-matchers (>= 1.4.1, < 3.0) 49 | shoulda-context (1.2.1) 50 | shoulda-matchers (2.8.0) 51 | activesupport (>= 3.0.0) 52 | sqlite3 (1.3.10) 53 | thor (0.19.1) 54 | thread_safe (0.3.5) 55 | tzinfo (1.2.2) 56 | thread_safe (~> 0.1) 57 | 58 | PLATFORMS 59 | ruby 60 | 61 | DEPENDENCIES 62 | RedCloth 63 | activerecord (~> 4.2.3) 64 | activesupport (~> 4.2.3) 65 | acts_as_markup! 66 | appraisal 67 | bluecloth 68 | brianjlandau-sdoc-helpers 69 | maruku 70 | rdoc (~> 4.0) 71 | redcarpet 72 | rpeg-markdown 73 | sdoc 74 | shoulda 75 | sqlite3 76 | -------------------------------------------------------------------------------- /lib/acts_as_markup.rb: -------------------------------------------------------------------------------- 1 | require 'set' 2 | require 'active_support' 3 | require 'active_support/core_ext' 4 | 5 | require 'acts_as_markup/version' 6 | require 'acts_as_markup/railtie' if defined?(Rails) 7 | 8 | module ActsAsMarkup 9 | # This exception is raised when an unsupported markup language is supplied to acts_as_markup. 10 | class UnsupportedMarkupLanguage < ArgumentError 11 | end 12 | 13 | # This exception is raised when an unsupported Markdown library is set to the config value. 14 | class UnsportedMarkdownLibrary < ArgumentError 15 | end 16 | 17 | MARKDOWN_LIBS = { :rdiscount => {:class_name => "RDiscount", 18 | :lib_name => "rdiscount"}, 19 | :bluecloth => {:class_name => "BlueClothText", 20 | :lib_name => "bluecloth"}, 21 | :rpeg => {:class_name => "PEGMarkdown", 22 | :lib_name => "peg_markdown"}, 23 | :maruku => {:class_name => "Maruku", 24 | :lib_name => "maruku"}, 25 | :redcarpet => {:class_name => "RedcarpetText", 26 | :lib_name => 'redcarpet'} } 27 | 28 | LIBRARY_EXTENSIONS = ::Set.new(Dir[File.join(File.expand_path(File.dirname(__FILE__)), 'acts_as_markup/exts/*.rb')].map {|file| File.basename(file, '.rb')}).delete('string') 29 | 30 | mattr_accessor :markdown_library 31 | 32 | # Returns the version string for the library. 33 | class << self 34 | def version 35 | VERSION 36 | end 37 | 38 | def markup_class(markup_name) 39 | load_markup_class(markup_name) 40 | end 41 | 42 | private 43 | 44 | def get_markdown_class 45 | if ActsAsMarkup::MARKDOWN_LIBS.keys.include? ActsAsMarkup.markdown_library 46 | markdown_library_names = ActsAsMarkup::MARKDOWN_LIBS[ActsAsMarkup.markdown_library] 47 | require markdown_library_names[:lib_name] 48 | require_extensions(markdown_library_names[:lib_name]) 49 | return markdown_library_names[:class_name].constantize 50 | else 51 | raise ActsAsMarkup::UnsportedMarkdownLibrary, "#{ActsAsMarkup.markdown_library} is not currently supported." 52 | end 53 | end 54 | 55 | def require_extensions(library)# :nodoc: 56 | if ActsAsMarkup::LIBRARY_EXTENSIONS.include? library.to_s 57 | require "acts_as_markup/exts/#{library}" 58 | end 59 | end 60 | 61 | def require_library_and_get_class(language) 62 | case language 63 | when :markdown 64 | return get_markdown_class 65 | when :textile 66 | require 'redcloth' 67 | return RedCloth 68 | when :rdoc 69 | require 'rdoc' 70 | require_extensions 'rdoc' 71 | return RDocText 72 | else 73 | return String 74 | end 75 | end 76 | 77 | def load_markup_class(markup_name) 78 | if [:markdown, :textile, :rdoc].include?(markup_name.to_sym) 79 | require_library_and_get_class(markup_name.to_sym) 80 | else 81 | raise ActsAsMarkup::UnsupportedMarkupLanguage, "#{markup_name} is not a currently supported markup language." 82 | end 83 | end 84 | end 85 | 86 | end 87 | 88 | ActiveSupport.run_load_hooks(:acts_as_markup, ActsAsMarkup) 89 | -------------------------------------------------------------------------------- /lib/acts_as_markup/active_record_extension.rb: -------------------------------------------------------------------------------- 1 | module ActsAsMarkup 2 | module ActiveRecordExtension 3 | extend ActiveSupport::Concern 4 | 5 | def string_for_markup_column(column_name) 6 | self[column_name].to_s 7 | end 8 | 9 | module ClassMethods 10 | 11 | # This allows you to specify columns you want to define as containing 12 | # Markdown, Textile, or RDoc content. 13 | # Then you can simply call .to_html method on the attribute. 14 | # 15 | # You can also specify the language as :variable. The language used 16 | # to process the column will be based on another column. By default a column 17 | # named "markup_language" is used, but this can be changed by providing 18 | # a :language_column option. When a value is accessed it will create 19 | # the correct object (Markdown, Textile, or RDoc) based on the value 20 | # of the language column. If any value besides markdown, textile, or 21 | # RDoc is supplied for the markup language the text will pass through as a string. 22 | # 23 | # You can specify additional options to pass to the markup library by using 24 | # :markdown_options, :textile_options . 25 | # RDoc does not support any useful options. The options should be given as an array 26 | # of arguments. You can specify options for more than one language when using 27 | # :variable. See each library's documentation for more details on what 28 | # options are available. 29 | # 30 | # 31 | # ==== Examples 32 | # 33 | # ===== Using Markdown language 34 | # 35 | # class Post < ActiveRecord 36 | # acts_as_markup :language => :markdown, :columns => [:body] 37 | # end 38 | # 39 | # @post = Post.find(:first) 40 | # @post.body.to_s # => "## Markdown Headline" 41 | # @post.body.to_html # => "

Markdown Headline

" 42 | # 43 | # 44 | # ===== Using variable language 45 | # 46 | # class Post < ActiveRecord 47 | # acts_as_markup :language => :variable, :columns => [:body], :language_column => 'language_name' 48 | # end 49 | # 50 | # @post = Post.find(:first) 51 | # @post.language_name # => "markdown" 52 | # @post.body.to_s # => "## Markdown Headline" 53 | # @post.body.to_html # => "

Markdown Headline

" 54 | # 55 | # 56 | # ===== Using options 57 | # 58 | # class Post < ActiveRecord 59 | # acts_as_markup :language => :markdown, :columns => [:body], :markdown_options => [ :filter_html ] 60 | # end 61 | # 62 | # class Post < ActiveRecord 63 | # acts_as_markup :language => :textile, :columns => [:body], :textile_options => [ [ :filter_html ] ] 64 | # end 65 | # 66 | # 67 | def acts_as_markup(options) 68 | options.reverse_merge!(:language_column => :markup_language) 69 | 70 | include InstanceMethods 71 | 72 | unless options[:language].to_sym == :variable 73 | define_markup_columns_reader_methods(options) 74 | else 75 | define_variable_markup_columns_reader_methods(options) 76 | end 77 | end 78 | 79 | # This is a convenience method for 80 | # `acts_as_markup :language => :markdown, :columns => [:body]` 81 | # Additional options can be given at the end, if necessary. 82 | # 83 | def acts_as_markdown(*columns) 84 | options = columns.extract_options! 85 | acts_as_markup options.merge(:language => :markdown, :columns => columns) 86 | end 87 | 88 | # This is a convenience method for 89 | # `acts_as_markup :language => :textile, :columns => [:body]` 90 | # Additional options can be given at the end, if necessary. 91 | # 92 | def acts_as_textile(*columns) 93 | options = columns.extract_options! 94 | acts_as_markup options.merge(:language => :textile, :columns => columns) 95 | end 96 | 97 | # This is a convenience method for 98 | # `acts_as_markup :language => :rdoc, :columns => [:body]` 99 | # Additional options can be given at the end, if necessary. 100 | # 101 | def acts_as_rdoc(*columns) 102 | options = columns.extract_options! 103 | acts_as_markup options.merge(:language => :rdoc, :columns => columns) 104 | end 105 | 106 | private 107 | 108 | def define_markup_columns_reader_methods(options) 109 | markup_options = options["#{options[:language]}_options".to_sym] || [] 110 | 111 | options[:columns].each do |col| 112 | define_method col do 113 | if instance_variable_defined?("@#{col}") && !send("#{col}_changed?") 114 | instance_variable_get("@#{col}") 115 | else 116 | instance_variable_set("@#{col}", markup_class(options[:language]).new(self[col].to_s, *markup_options)) 117 | end 118 | end 119 | end 120 | end 121 | 122 | def define_variable_markup_columns_reader_methods(options) 123 | options[:columns].each do |col| 124 | define_method col do 125 | if instance_variable_defined?("@#{col}") 126 | unless send("#{col}_changed?") || send("#{options[:language_column]}_changed?") 127 | return instance_variable_get("@#{col}") 128 | end 129 | end 130 | instance_variable_set("@#{col}", case send(options[:language_column]) 131 | when /markdown/i 132 | markup_class(:markdown).new string_for_markup_column(col), *(options[:markdown_options] || []) 133 | when /textile/i 134 | markup_class(:textile).new string_for_markup_column(col), *(options[:textile_options] || []) 135 | when /rdoc/i 136 | markup_class(:rdoc).new string_for_markup_column(col) 137 | else 138 | String(self[col]) 139 | end) 140 | end 141 | end 142 | end 143 | 144 | end 145 | 146 | module InstanceMethods 147 | def markup_class(markup_name) 148 | ActsAsMarkup.markup_class(markup_name) 149 | end 150 | end 151 | end 152 | end 153 | -------------------------------------------------------------------------------- /lib/acts_as_markup/exts/bluecloth.rb: -------------------------------------------------------------------------------- 1 | class BlueClothText < BlueCloth 2 | include Stringlike 3 | 4 | def initialize(string, options = BlueCloth::DEFAULT_OPTIONS) 5 | @string = string 6 | super 7 | end 8 | 9 | def to_s 10 | @string 11 | end 12 | 13 | def blank? 14 | @string.blank? 15 | end 16 | end -------------------------------------------------------------------------------- /lib/acts_as_markup/exts/maruku.rb: -------------------------------------------------------------------------------- 1 | require 'maruku' 2 | 3 | class Maruku 4 | include Stringlike 5 | 6 | attr_reader :text 7 | 8 | def initialize(s=nil, meta={}) 9 | super(nil) 10 | self.attributes.merge! meta 11 | if s 12 | @text = s 13 | parse_doc(s) 14 | end 15 | end 16 | 17 | # Used to get the original Markdown text. 18 | def to_s 19 | @text 20 | end 21 | 22 | # used to be compatable with Rails/ActiveSupport 23 | def blank? 24 | @text.blank? 25 | end 26 | 27 | end 28 | 29 | class String 30 | alias_method :to_html, :to_s 31 | 32 | def to_xml 33 | REXML::Text.new(self) 34 | end 35 | end 36 | 37 | module MaRuKu # :nodoc: 38 | module Out # :nodoc: 39 | module HTML 40 | 41 | # We patch this method to play nicely with our own modifications of String. 42 | # 43 | # It originally used a +to_html+ method on String we've swapped this out for a +to_xml+ 44 | # method because we need +to_html+ to return the original text on plain text fields of 45 | # the variable language option on +acts_as_markup+ 46 | def array_to_html(array) 47 | elements = [] 48 | array.each do |item| 49 | method = item.kind_of?(MDElement) ? "to_html_#{item.node_type}" : "to_xml" 50 | unless item.respond_to?(method) 51 | next 52 | end 53 | 54 | html_text = item.send(method) 55 | if html_text.nil? 56 | raise "Nil html created by method #{method}:\n#{html_text.inspect}\n for object #{item.inspect[0,300]}" 57 | end 58 | 59 | if html_text.kind_of?Array 60 | elements = elements + html_text 61 | else 62 | elements << html_text 63 | end 64 | end 65 | elements 66 | end 67 | 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/acts_as_markup/exts/peg_markdown.rb: -------------------------------------------------------------------------------- 1 | require 'peg_markdown' 2 | 3 | class PEGMarkdown 4 | include Stringlike 5 | 6 | # used to be compatable with Rails/ActiveSupport 7 | def blank? 8 | self.text.blank? 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/acts_as_markup/exts/rdiscount.rb: -------------------------------------------------------------------------------- 1 | require 'rdiscount' 2 | 3 | class RDiscount 4 | include Stringlike 5 | 6 | # Used to get the original Markdown text. 7 | def to_s 8 | self.text 9 | end 10 | 11 | # used to be compatable with Rails/ActiveSupport 12 | def blank? 13 | self.text.blank? 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/acts_as_markup/exts/rdoc.rb: -------------------------------------------------------------------------------- 1 | require 'rdoc' 2 | 3 | class RDocWithHyperlinkToHtml < RDoc::Markup::ToHtml 4 | 5 | # Generate a hyperlink for url, labeled with text. Handle the 6 | # special cases for img: and link: described under handle_special_HYPEDLINK 7 | # 8 | def gen_url(url, text) 9 | if url =~ /([A-Za-z]+):(.*)/ 10 | type = $1 11 | path = $2 12 | else 13 | type = "http" 14 | path = url 15 | url = "http://#{url}" 16 | end 17 | 18 | if type == "link" 19 | if path[0,1] == '#' # is this meaningful? 20 | url = path 21 | else 22 | url = HTMLGenerator.gen_url(@from_path, path) 23 | end 24 | end 25 | 26 | if (type == "http" || type == "link") && url =~ /\.(gif|png|jpg|jpeg|bmp)$/ 27 | "" 28 | else 29 | "#{text.sub(%r{^#{type}:/*}, '')}" 30 | end 31 | end 32 | 33 | # And we're invoked with a potential external hyperlink mailto: 34 | # just gets inserted. http: links are checked to see if they 35 | # reference an image. If so, that image gets inserted using an 36 | # tag. Otherwise a conventional is used. We also 37 | # support a special type of hyperlink, link:, which is a reference 38 | # to a local file whose path is relative to the --op directory. 39 | # 40 | def handle_special_HYPERLINK(special) 41 | url = special.text 42 | gen_url(url, url) 43 | end 44 | 45 | # Here's a hypedlink where the label is different to the URL 46 | #

Textile Test Text<\/h2>/, @textile_post.body.to_html) 38 | end 39 | 40 | context "changing value of markup field should return new markup object" do 41 | setup do 42 | @markdown_old_body = @markdown_post.body 43 | @markdown_post.body = "`@count = 20`" 44 | @textile_old_body = @textile_post.body 45 | @textile_post.body = "@@count = 20@" 46 | end 47 | 48 | should "still have an markup object but not the same object" do 49 | assert_kind_of RedCloth::TextileDoc, @textile_post.body 50 | assert_not_same @markdown_post.body, @markdown_old_body 51 | assert_kind_of RDiscount, @markdown_post.body 52 | assert_not_same @textile_post.body, @textile_old_body 53 | end 54 | 55 | should "return correct text for `to_s`" do 56 | assert_equal "`@count = 20`", @markdown_post.body.to_s 57 | assert_equal "@@count = 20@", @textile_post.body.to_s 58 | end 59 | 60 | should "return correct HTML for the `to_html` method" do 61 | assert_match(/\s*\@count\s\=\s20\s*<\/code>/, @markdown_post.body.to_html) 62 | assert_match(/\@count\s\=\s20<\/code>/, @textile_post.body.to_html) 63 | end 64 | 65 | teardown do 66 | @markdown_old_body, @textile_old_body = nil 67 | end 68 | end 69 | 70 | teardown do 71 | @textile_text, @textile_post, @markdown_text, @markdown_post = nil 72 | TextilePost.delete_all 73 | MarkdownPost.delete_all 74 | end 75 | end 76 | 77 | context 'acts_as_markup with variable language' do 78 | setup do 79 | ActsAsMarkup.markdown_library = :rdiscount 80 | class ::VariablePost < ActiveRecord::Base 81 | acts_as_markup :language => :variable, :columns => [:body] 82 | end 83 | end 84 | 85 | context "with a Markdown post" do 86 | setup do 87 | @markdown_text = '## Markdown Test Text' 88 | @markdown_post = VariablePost.create!(:title => 'Blah', :body => @markdown_text, :markup_language => 'Markdown') 89 | end 90 | 91 | should "have a markup object returned for the column value" do 92 | assert_kind_of RDiscount, @markdown_post.body 93 | end 94 | 95 | should "return original markup text for a `to_s` method call on the column value" do 96 | assert_equal @markdown_text, @markdown_post.body.to_s 97 | end 98 | 99 | should "return formated html for a `to_html` method call on the column value" do 100 | assert_match(/\s*Markdown Test Text\s*<\/h2>/, @markdown_post.body.to_html) 101 | end 102 | 103 | context "changing value of markup field should return new markup object" do 104 | setup do 105 | @markdown_old_body = @markdown_post.body 106 | @markdown_post.body = "`@count = 20`" 107 | end 108 | 109 | should "still have an markup object but not the same object" do 110 | assert_not_same @markdown_post.body, @markdown_old_body 111 | assert_kind_of RDiscount, @markdown_post.body 112 | end 113 | 114 | should "return correct text for `to_s`" do 115 | assert_equal "`@count = 20`", @markdown_post.body.to_s 116 | end 117 | 118 | should "return correct HTML for the `to_html` method" do 119 | assert_match(/\s*\@count\s\=\s20\s*<\/code>/, @markdown_post.body.to_html) 120 | end 121 | 122 | teardown do 123 | @markdown_old_body = nil 124 | end 125 | end 126 | 127 | teardown do 128 | @markdown_text, @markup_post = nil 129 | end 130 | end 131 | 132 | context "with a Textile post" do 133 | setup do 134 | @textile_text = "h2. Textile Test Text" 135 | @textile_post = VariablePost.create!(:title => 'Blah', :body => @textile_text, :markup_language => 'Textile') 136 | end 137 | 138 | should "have a markup object returned for the column value" do 139 | assert_kind_of RedCloth::TextileDoc, @textile_post.body 140 | end 141 | 142 | should "return original markup text for a `to_s` method call on the column value" do 143 | assert_equal @textile_text, @textile_post.body.to_s 144 | end 145 | 146 | should "return formated html for a `to_html` method call on the column value" do 147 | assert_match(/

Textile Test Text<\/h2>/, @textile_post.body.to_html) 148 | end 149 | 150 | context "changing value of markup field should return new markup object" do 151 | setup do 152 | @textile_old_body = @textile_post.body 153 | @textile_post.body = "@@count = 20@" 154 | end 155 | 156 | should "still have an markup object but not the same object" do 157 | assert_kind_of RedCloth::TextileDoc, @textile_post.body 158 | assert_not_same @textile_post.body, @textile_old_body 159 | end 160 | 161 | should "return correct text for `to_s`" do 162 | assert_equal "@@count = 20@", @textile_post.body.to_s 163 | end 164 | 165 | should "return correct HTML for the `to_html` method" do 166 | assert_match(/\@count\s\=\s20<\/code>/, @textile_post.body.to_html) 167 | end 168 | 169 | teardown do 170 | @textile_old_body = nil 171 | end 172 | end 173 | 174 | teardown do 175 | @textile_text, @textile_post = nil 176 | end 177 | end 178 | 179 | context 'with a RDoc post' do 180 | setup do 181 | @rdoctext = "== RDoc Test Text" 182 | @rdoc_post = VariablePost.create!(:title => 'Blah', :body => @rdoctext, :markup_language => 'RDoc') 183 | end 184 | 185 | should "have a RDocText object returned for the column value" do 186 | assert_kind_of RDocText, @rdoc_post.body 187 | end 188 | 189 | should "return original RDoc text for a `to_s` method call on the column value" do 190 | assert_equal @rdoctext, @rdoc_post.body.to_s 191 | end 192 | 193 | should "return formated html for a `to_html` method call on the column value" do 194 | assert_match(/]*>\s*RDoc Test Text.*<\/h2>/, @rdoc_post.body.to_html) 195 | end 196 | 197 | context "changing value of RDoc field should return new RDoc object" do 198 | setup do 199 | @old_body = @rdoc_post.body 200 | @rdoc_post.body = "http://www.example.com/" 201 | end 202 | 203 | should "still have an RDocText object but not the same object" do 204 | assert_kind_of RDocText, @rdoc_post.body 205 | assert_not_same @rdoc_post.body, @old_body 206 | end 207 | 208 | should "return correct text for `to_s`" do 209 | assert_equal "http://www.example.com/", @rdoc_post.body.to_s 210 | end 211 | 212 | should "return correct HTML for the `to_html` method" do 213 | assert_match(/www.example.com<\/a>/, @rdoc_post.body.to_html) 214 | end 215 | 216 | teardown do 217 | @old_body = nil 218 | end 219 | end 220 | 221 | teardown do 222 | @rdoctext, @rdoc_post = nil 223 | end 224 | end 225 | 226 | context "with a plain text post" do 227 | setup do 228 | @plain_text = "Hahaha!!!" 229 | @plain_text_post = VariablePost.create!(:title => 'Blah', :body => @plain_text, :markup_language => 'text') 230 | end 231 | 232 | should "have a string object returned for the column value" do 233 | assert_kind_of String, @plain_text_post.body 234 | end 235 | 236 | should "return the original string with a `to_s` method call on the column value" do 237 | assert_equal @plain_text, @plain_text_post.body.to_s 238 | end 239 | 240 | should "return the original string with a `to_html` method call on the column value" do 241 | assert_equal @plain_text, @plain_text_post.body.to_html 242 | end 243 | 244 | context "changing value of markup field should return new markup object" do 245 | setup do 246 | @plaintext_old_body = @plain_text_post.body 247 | @plain_text_post.body = "Lorem ipsum dolor sit amet" 248 | end 249 | 250 | should "still have an markup object but not the same object" do 251 | assert_kind_of String, @plain_text_post.body 252 | assert_not_same @plain_text_post.body, @plaintext_old_body 253 | end 254 | 255 | should "return correct text for `to_s`" do 256 | assert_equal "Lorem ipsum dolor sit amet", @plain_text_post.body.to_s 257 | end 258 | 259 | teardown do 260 | @textile_old_body = nil 261 | end 262 | end 263 | 264 | teardown do 265 | @textile_text, @textile_post = nil 266 | end 267 | end 268 | 269 | teardown do 270 | VariablePost.delete_all 271 | end 272 | end 273 | 274 | context 'acts_as_markup with variable language setting the language column' do 275 | setup do 276 | ActsAsMarkup.markdown_library = :rdiscount 277 | class ::VariableLanguagePost < ActiveRecord::Base 278 | acts_as_markup :language => :variable, :columns => [:body], :language_column => :language_name 279 | end 280 | end 281 | 282 | should "use the correct language column" do 283 | markdown_text = '## Markdown Test Text' 284 | markdown_post = VariableLanguagePost.create!(:title => 'Blah', :body => markdown_text, :language_name => 'Markdown') 285 | 286 | assert_kind_of RDiscount, markdown_post.body 287 | assert_equal markdown_text, markdown_post.body.to_s 288 | assert_match(/\s*Markdown Test Text\s*<\/h2>/, markdown_post.body.to_html) 289 | end 290 | 291 | teardown do 292 | VariableLanguagePost.delete_all 293 | end 294 | end 295 | 296 | context 'with a nil value for the text' do 297 | setup do 298 | @text = nil 299 | end 300 | 301 | context 'with textile' do 302 | setup do 303 | ActsAsMarkup.markup_class(:textile) 304 | class ::Post < ActiveRecord::Base 305 | acts_as_textile :body 306 | end 307 | @post = Post.create!(:title => 'Blah', :body => @text) 308 | end 309 | 310 | should 'return a blank string for `to_s` method' do 311 | assert_equal @post.body.to_s, '' 312 | end 313 | 314 | should 'return true for .blank?' do 315 | assert @post.body.blank? 316 | end 317 | 318 | should 'return a blank string for `to_html` method' do 319 | assert_match(/[\n\s]*/, @post.body.to_html) 320 | end 321 | 322 | should "have a RedCloth object returned for the column value" do 323 | assert_kind_of RedCloth::TextileDoc, @post.body 324 | end 325 | 326 | teardown do 327 | @post = nil 328 | Post.delete_all 329 | end 330 | end 331 | 332 | context 'with RDoc' do 333 | setup do 334 | ActsAsMarkup.markup_class(:rdoc) 335 | class ::Post < ActiveRecord::Base 336 | acts_as_rdoc :body 337 | end 338 | @post = Post.create!(:title => 'Blah', :body => @text) 339 | end 340 | 341 | should 'return a blank string for `to_s` method' do 342 | assert_equal @post.body.to_s, '' 343 | end 344 | 345 | should 'return true for .blank?' do 346 | assert @post.body.blank? 347 | end 348 | 349 | should 'return a blank string for `to_html` method' do 350 | assert_match(/[\n\s]*/, @post.body.to_html) 351 | end 352 | 353 | should "have a RDocText object returned for the column value" do 354 | assert_kind_of RDocText, @post.body 355 | end 356 | 357 | teardown do 358 | @post = nil 359 | Post.delete_all 360 | end 361 | end 362 | 363 | context 'with RDiscount Markdown' do 364 | setup do 365 | ActsAsMarkup.markdown_library = :rdiscount 366 | ActsAsMarkup.markup_class(:markdown) 367 | class ::Post < ActiveRecord::Base 368 | acts_as_markdown :body 369 | end 370 | @post = Post.create!(:title => 'Blah', :body => @text) 371 | end 372 | 373 | should 'return a blank string for `to_s` method' do 374 | assert_equal @post.body.to_s, '' 375 | end 376 | 377 | should 'return true for .blank?' do 378 | assert @post.body.blank? 379 | end 380 | 381 | should 'return a blank string for `to_html` method' do 382 | assert_match(/[\n\s]*/, @post.body.to_html) 383 | end 384 | 385 | should "have a RDiscount object returned for the column value" do 386 | assert_kind_of RDiscount, @post.body 387 | end 388 | 389 | teardown do 390 | @post = nil 391 | Post.delete_all 392 | end 393 | end 394 | 395 | context 'with BlueCloth Markdown' do 396 | setup do 397 | ActsAsMarkup.markdown_library = :bluecloth 398 | ActsAsMarkup.markup_class(:markdown) 399 | class ::Post < ActiveRecord::Base 400 | acts_as_markdown :body 401 | end 402 | @post = Post.create!(:title => 'Blah', :body => @text) 403 | end 404 | 405 | should 'return a blank string for `to_s` method' do 406 | assert_equal '', @post.body.to_s 407 | end 408 | 409 | should 'return true for .blank?' do 410 | assert @post.body.blank? 411 | end 412 | 413 | should 'return a blank string for `to_html` method' do 414 | assert_match(/[\n\s]*/, @post.body.to_html) 415 | end 416 | 417 | should "have a BlueCloth object returned for the column value" do 418 | assert_kind_of BlueCloth, @post.body 419 | end 420 | 421 | teardown do 422 | @post = nil 423 | Post.delete_all 424 | end 425 | end 426 | 427 | context 'with Ruby PEG Markdown' do 428 | setup do 429 | ActsAsMarkup.markdown_library = :rpeg 430 | ActsAsMarkup.markup_class(:markdown) 431 | class ::Post < ActiveRecord::Base 432 | acts_as_markdown :body 433 | end 434 | @post = Post.create!(:title => 'Blah', :body => @text) 435 | end 436 | 437 | should 'return a blank string for `to_s` method' do 438 | assert_equal @post.body.to_s, '' 439 | end 440 | 441 | should 'return true for .blank?' do 442 | assert @post.body.blank? 443 | end 444 | 445 | should 'return a blank string for `to_html` method' do 446 | assert_match(/[\n\s]*/, @post.body.to_html) 447 | end 448 | 449 | should "have a PEGMarkdown object returned for the column value" do 450 | assert_kind_of ::PEGMarkdown, @post.body 451 | end 452 | 453 | teardown do 454 | @post = nil 455 | Post.delete_all 456 | end 457 | end 458 | 459 | context 'with Maruku Markdown' do 460 | setup do 461 | ActsAsMarkup.markdown_library = :maruku 462 | ActsAsMarkup.markup_class(:markdown) 463 | class ::Post < ActiveRecord::Base 464 | acts_as_markdown :body 465 | end 466 | @post = Post.create!(:title => 'Blah', :body => @text) 467 | end 468 | 469 | should 'return a blank string for `to_s` method' do 470 | assert_equal @post.body.to_s, '' 471 | end 472 | 473 | should 'return true for .blank?' do 474 | assert @post.body.blank? 475 | end 476 | 477 | should 'return a blank string for `to_html` method' do 478 | assert_match(/[\n\s]*/, @post.body.to_html) 479 | end 480 | 481 | should "have a Maruku object returned for the column value" do 482 | assert_kind_of Maruku, @post.body 483 | end 484 | 485 | teardown do 486 | @post = nil 487 | Post.delete_all 488 | end 489 | end 490 | 491 | 492 | context 'with Redcarpet Markdown' do 493 | setup do 494 | ActsAsMarkup.markdown_library = :redcarpet 495 | ActsAsMarkup.markup_class(:markdown) 496 | class ::Post < ActiveRecord::Base 497 | acts_as_markdown :body 498 | end 499 | @post = Post.create!(:title => 'Blah', :body => @text) 500 | end 501 | 502 | should 'return a blank string for `to_s` method' do 503 | assert_equal @post.body.to_s, '' 504 | end 505 | 506 | should 'return true for .blank?' do 507 | assert @post.body.blank? 508 | end 509 | 510 | should 'return a blank string for `to_html` method' do 511 | assert_match(/[\n\s]*/, @post.body.to_html) 512 | end 513 | 514 | should "have a Maruku object returned for the column value" do 515 | assert_kind_of ::RedcarpetText, @post.body 516 | end 517 | 518 | teardown do 519 | @post = nil 520 | Post.delete_all 521 | end 522 | end 523 | end 524 | 525 | context 'acts_as_markup with bad language name' do 526 | should 'raise exception when a non-supported language is passed to acts_as_markup' do 527 | assert_raise ActsAsMarkup::UnsupportedMarkupLanguage do 528 | ActsAsMarkup.markup_class(:fake) 529 | end 530 | end 531 | end 532 | 533 | context 'acts_as_markup with bad markdown library' do 534 | should 'raise exception when a non-supported library is set as the markdown library attribute on ActsAsMarkup' do 535 | ActsAsMarkup.markdown_library = :fake 536 | assert_raise ActsAsMarkup::UnsportedMarkdownLibrary do 537 | ActsAsMarkup.markup_class(:markdown) 538 | end 539 | end 540 | end 541 | 542 | def teardown 543 | teardown_db 544 | end 545 | end 546 | 547 | -------------------------------------------------------------------------------- /test/acts_as_rdoc_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | 3 | class ActsAsRDocTest < ActsAsMarkupTestCase 4 | context 'acts_as_rdoc' do 5 | setup do 6 | @rdoctext = "== RDoc Test Text" 7 | class ::Post < ActiveRecord::Base 8 | acts_as_rdoc :body 9 | end 10 | @post = Post.create!(:title => 'Blah', :body => @rdoctext) 11 | end 12 | 13 | should "have a RDocText object returned for the column value" do 14 | assert_kind_of RDocText, @post.body 15 | end 16 | 17 | should "return original RDoc text for a `to_s` method call on the column value" do 18 | assert_equal @rdoctext, @post.body.to_s 19 | end 20 | 21 | should 'return false for .blank?' do 22 | assert !@post.body.blank? 23 | end 24 | 25 | should "return formated html for a `to_html` method call on the column value" do 26 | assert_match(/]*>\s*RDoc Test Text.*<\/h2>/, @post.body.to_html) 27 | end 28 | 29 | context "changing value of RDoc field should return new RDoc object" do 30 | setup do 31 | @old_body = @post.body 32 | @post.body = "http://www.example.com/" 33 | end 34 | 35 | should "still have an RDocText object but not the same object" do 36 | assert_kind_of RDocText, @post.body 37 | assert_not_same @post.body, @old_body 38 | end 39 | 40 | should "return correct text for `to_s`" do 41 | assert_equal "http://www.example.com/", @post.body.to_s 42 | end 43 | 44 | should "return correct HTML for the `to_html` method" do 45 | assert_match(/www.example.com<\/a>/, @post.body.to_html) 46 | end 47 | 48 | teardown do 49 | @old_body = nil 50 | end 51 | end 52 | 53 | teardown do 54 | @rdoctext, @post = nil 55 | Post.delete_all 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /test/acts_as_textile_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | 3 | class ActsAsTextileTest < ActsAsMarkupTestCase 4 | context 'acts_as_textile' do 5 | setup do 6 | @textile_text = "h2. Textile Test Text" 7 | class ::Post < ActiveRecord::Base 8 | acts_as_textile :body 9 | end 10 | @post = Post.create!(:title => 'Blah', :body => @textile_text) 11 | end 12 | 13 | should "have a RedCloth object returned for the column value" do 14 | assert_kind_of RedCloth::TextileDoc, @post.body 15 | end 16 | 17 | should "return original textile text for a `to_s` method call on the column value" do 18 | assert_equal @textile_text, @post.body.to_s 19 | end 20 | 21 | should 'return false for .blank?' do 22 | assert !@post.body.blank? 23 | end 24 | 25 | should "return formated html for a `to_html` method call on the column value" do 26 | assert_match(/

Textile Test Text<\/h2>/, @post.body.to_html) 27 | end 28 | 29 | should "not return escaped html" do 30 | @post.body = "h2. Textile Test Text" 31 | assert_match(/Test<\/i>/, @post.body.to_html) 32 | end 33 | 34 | context "changing value of textile field should return new textile object" do 35 | setup do 36 | @old_body = @post.body 37 | @post.body = "@@count = 20@" 38 | end 39 | 40 | should "still have an RedCloth object but not the same object" do 41 | assert_kind_of RedCloth::TextileDoc, @post.body 42 | assert_not_same @post.body, @old_body 43 | end 44 | 45 | should "return correct text for `to_s`" do 46 | assert_equal "@@count = 20@", @post.body.to_s 47 | end 48 | 49 | should "return correct HTML for the `to_html` method" do 50 | assert_match(/\@count\s\=\s20<\/code>/, @post.body.to_html) 51 | end 52 | 53 | teardown do 54 | @old_body = nil 55 | end 56 | end 57 | 58 | teardown do 59 | @textile_text, @post = nil 60 | Post.delete_all 61 | end 62 | end 63 | 64 | context 'acts_as_textile with options' do 65 | setup do 66 | class ::Post 67 | acts_as_textile :body, :textile_options => [ [ :filter_html ] ] 68 | end 69 | @post = Post.new(:title => 'Blah') 70 | end 71 | 72 | should "return escaped html because of :filter_html" do 73 | @post.body = "h2. Textile Test Text" 74 | assert_match(/<i>Test<\/i>/, @post.body.to_html) 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler' 3 | begin 4 | Bundler.setup(:default, :development) 5 | rescue Bundler::BundlerError => e 6 | $stderr.puts e.message 7 | $stderr.puts "Run `bundle install` to install missing gems" 8 | exit e.status_code 9 | end 10 | require 'active_support/version' 11 | if ActiveSupport::VERSION::MAJOR >= 4 12 | require 'minitest/autorun' 13 | else 14 | require 'test/unit' 15 | end 16 | gem 'sqlite3' 17 | require 'shoulda' 18 | require 'active_support' 19 | require 'active_support/test_case' 20 | 21 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 22 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 23 | 24 | require 'acts_as_markup' 25 | require 'acts_as_markup/exts/string' 26 | require 'acts_as_markup/stringlike' 27 | require 'acts_as_markup/active_record_extension' 28 | require 'active_record' 29 | 30 | ActiveRecord::Schema.verbose = false 31 | ActiveRecord::Base.send :include, ActsAsMarkup::ActiveRecordExtension 32 | ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") 33 | ActsAsMarkup.markdown_library = :rdiscount 34 | 35 | def setup_db 36 | ActiveRecord::Schema.define(:version => 1) do 37 | create_table :posts do |t| 38 | t.column :title, :string 39 | t.column :body, :text 40 | t.timestamps 41 | end 42 | 43 | create_table :markdown_posts do |t| 44 | t.column :title, :string 45 | t.column :body, :text 46 | t.timestamps 47 | end 48 | 49 | create_table :textile_posts do |t| 50 | t.column :title, :string 51 | t.column :body, :text 52 | t.timestamps 53 | end 54 | 55 | create_table :variable_posts do |t| 56 | t.column :title, :string 57 | t.column :body, :text 58 | t.column :markup_language, :string 59 | t.timestamps 60 | end 61 | 62 | create_table :variable_language_posts do |t| 63 | t.column :title, :string 64 | t.column :body, :text 65 | t.column :language_name, :string 66 | t.timestamps 67 | end 68 | end 69 | end 70 | 71 | def teardown_db 72 | ActiveRecord::Base.connection.tables.each do |table| 73 | ActiveRecord::Base.connection.drop_table(table) 74 | end 75 | end 76 | 77 | class ActsAsMarkupTestCase < ActiveSupport::TestCase 78 | def setup 79 | setup_db 80 | end 81 | 82 | def teardown 83 | teardown_db 84 | end 85 | 86 | def self.should_act_like_a_string 87 | should "act like a string" do 88 | assert_equal @post.body.split(' '), ['##', 'Markdown', 'Test', 'Text'] 89 | assert @post.body.match(/Te[sx]t/) 90 | end 91 | end 92 | end 93 | --------------------------------------------------------------------------------