require 'active_record' module ActiveRecord # :nodoc: module Acts # :nodoc: module AsMarkup def self.included(base) # :nodoc: base.extend(ClassMethods) end module ClassMethods ## # This allows you to specify columns you want to define as containing # Markdown, Textile or Wikitext content. # Then you can simply call .to_html method on the attribute. # # You can also specify the language as :variable you will then # need to add an additional option of :language_column. When # a value is accessed it will create the correct object (Markdown, Textile, # or Wikitext) based on the value of the language column. If any value # besides markdown, textile, or wikitext is supplied for the markup language # the text will pass through as a string. # # # ==== Examples # # ===== Using Markdown language # # class Post < ActiveRecrod # acts_as_markup :language => :markdown, :columns => [:body] # end # # @post = Post.find(:first) # @post.body.to_s # => "## Markdown Headline" # @post.body.to_html # => "

Markdown Headline

" # # # ===== Using variable language # # class Post < ActiveRecrod # acts_as_markup :language => :variable, :columns => [:body], :language_column => 'markup_language' # end # # @post = Post.find(:first) # @post.markup_language # => "markdown" # @post.body.to_s # => "## Markdown Headline" # @post.body.to_html # => "

Markdown Headline

" # # def acts_as_markup(options) case options[:language].to_sym when :markdown klass = get_markdown_class when :textile require 'redcloth' klass = 'RedCloth' when :wikitext require 'wikitext' require_extensions 'wikitext' klass = 'WikitextString' when :variable markdown_klass = get_markdown_class require 'redcloth' require 'wikitext' require_extensions 'wikitext' textile_klass = 'RedCloth' wiki_klass = 'WikitextString' else raise ActsAsMarkup::UnsportedMarkupLanguage, "#{options[:langauge]} is not a currently supported markup language." end options[:columns].each do |col| unless options[:language].to_sym == :variable class_eval <<-EOV def #{col.to_s} if @#{col.to_s} if !self.#{col.to_s}_changed? return @#{col.to_s} end end @#{col.to_s} = #{klass}.new(self['#{col.to_s}'].to_s) end EOV else class_eval <<-EOV def #{col.to_s} if @#{col.to_s} unless self.#{col.to_s}_changed? || self.#{options[:language_column].to_s}_changed? return @#{col.to_s} end end case self.#{options[:language_column].to_s} when /markdown/i @#{col.to_s} = #{markdown_klass}.new(self['#{col.to_s}'].to_s) when /textile/i @#{col.to_s} = #{textile_klass}.new(self['#{col.to_s}'].to_s) when /wikitext/i @#{col.to_s} = #{wiki_klass}.new(self['#{col.to_s}'].to_s) else @#{col.to_s} = self['#{col.to_s}'] end end EOV end end end ## # This is a convenience method for # `acts_as_markup :language => :markdown, :columns => [:body]` # def acts_as_markdown(*columns) acts_as_markup :language => :markdown, :columns => columns end ## # This is a convenience method for # `acts_as_markup :language => :textile, :columns => [:body]` # def acts_as_textile(*columns) acts_as_markup :language => :textile, :columns => columns end ## # This is a convenience method for # `acts_as_markup :language => :wikitext, :columns => [:body]` # def acts_as_wikitext(*columns) acts_as_markup :language => :wikitext, :columns => columns end private def get_markdown_class if ActsAsMarkup::MARKDOWN_LIBS.keys.include? ActsAsMarkup.markdown_library markdown_library_names = ActsAsMarkup::MARKDOWN_LIBS[ActsAsMarkup.markdown_library] require markdown_library_names[:lib_name] require_extensions(markdown_library_names[:lib_name]) return markdown_library_names[:class_name] else raise ActsAsMarkup::UnsportedMarkdownLibrary, "#{ActsAsMarkup.markdown_library} is not currently supported." end end def require_extensions(library)# :nodoc: if %w(rdiscount maruku wikitext).include? library.to_s require "acts_as_markup/exts/#{library.to_s}" end end end end end end ActiveRecord::Base.send :include, ActiveRecord::Acts::AsMarkup