-
Notifications
You must be signed in to change notification settings - Fork 18
/
as_markup.rb
155 lines (144 loc) · 5.61 KB
/
as_markup.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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 <tt>.to_html</tt> method on the attribute.
#
# You can also specify the language as <tt>:variable</tt> you will then
# need to add an additional option of <tt>:language_column</tt>. 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 # => "<h2> Markdown Headline</h2>"
#
#
# ===== 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 # => "<h2> Markdown Headline</h2>"
#
#
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
# `<tt>acts_as_markup :language => :markdown, :columns => [:body]</tt>`
#
def acts_as_markdown(*columns)
acts_as_markup :language => :markdown, :columns => columns
end
##
# This is a convenience method for
# `<tt>acts_as_markup :language => :textile, :columns => [:body]</tt>`
#
def acts_as_textile(*columns)
acts_as_markup :language => :textile, :columns => columns
end
##
# This is a convenience method for
# `<tt>acts_as_markup :language => :wikitext, :columns => [:body]</tt>`
#
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