acts_as_markup 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ == 0.1.0 / 2008-08-04
2
+
3
+ * Initial Release
4
+ * Support for Markdown and Textile markup languages.
5
+ * `acts_as_markdown` and `acts_as_textile` convenience methods
6
+ * Support for BlueCloth, RDiscount and Ruyb PEG markdown processors.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
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.
data/Manifest.txt ADDED
@@ -0,0 +1,20 @@
1
+ History.txt
2
+ LICENSE.txt
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ acts_as_markup.gemspec
7
+ lib/acts/as_markup.rb
8
+ lib/acts_as_markup.rb
9
+ lib/acts_as_markup/exts/rdiscount.rb
10
+ tasks/bones.rake
11
+ tasks/gem.rake
12
+ tasks/git.rake
13
+ tasks/manifest.rake
14
+ tasks/post_load.rake
15
+ tasks/rdoc.rake
16
+ tasks/rubyforge.rake
17
+ tasks/setup.rb
18
+ tasks/test.rake
19
+ test/acts_as_markup_test.rb
20
+ test/test_helper.rb
data/README.rdoc ADDED
@@ -0,0 +1,74 @@
1
+ = acts_as_markup
2
+
3
+ by Brian Landau of Viget Labs <brian.landau@viget.com>
4
+
5
+ GitHub Project: http://github.com/vigetlabs/acts_as_markup
6
+
7
+ RDoc: http://viget.rubyforge.org/acts_as_markup
8
+
9
+
10
+ == DESCRIPTION:
11
+
12
+ Allows you to specify columns of an ActiveRecord model that contain Markdown or
13
+ Textile text. You may then use +to_s+ to get the original markdown or textile
14
+ text or +to_html+ to get the formated HTML.
15
+
16
+ This AR extension can use 3 different types of Markdown processing backends:
17
+ BlueCloth, RDiscount, or Ruby PEG. You specify which one you want to use by setting
18
+ a config value in your environment.rb file:
19
+
20
+ ActsAsMarkup.markdown_library = :bluecloth
21
+
22
+ By default RDiscount will be used.
23
+
24
+ == EXAMPLES:
25
+
26
+ ==== Using +acts_as_markdown+:
27
+
28
+ class Post < ActiveRecrod
29
+ acts_as_markdown :body
30
+ end
31
+
32
+ @post = Post.find(:first)
33
+ @post.body.to_s #=> "## Markdown Headline"
34
+ @post.body.to_html #=> "<h2> Markdown Headline</h2>"
35
+
36
+ ==== Using +acts_as_textile+:
37
+
38
+ class Post < ActiveRecrod
39
+ acts_as_textile :body
40
+ end
41
+
42
+ @post = Post.find(:first)
43
+ @post.body.to_s #=> "h2. Markdown Headline"
44
+ @post.body.to_html #=> "<h2>Markdown Headline</h2>"
45
+
46
+ ==== Using +acts_as_markup+:
47
+
48
+ class Post < ActiveRecrod
49
+ acts_as_markup :language => :markdown, :columns => [:body]
50
+ end
51
+
52
+ @post = Post.find(:first)
53
+ @post.body.to_s #=> "## Markdown Headline"
54
+ @post.body.to_html #=> "<h2> Markdown Headline</h2>"
55
+
56
+ == REQUIREMENTS:
57
+
58
+ You will need the RedCloth library for processing the Textile text.
59
+
60
+ You will also need to install some type of Markdown processor.
61
+ The three options currently supported are:
62
+
63
+ * BlueCloth
64
+ * RDiscount[http://github.com/rtomayko/rdiscount]
65
+ * {Ruby PEG}[http://github.com/rtomayko/rpeg-markdown/tree/master]
66
+
67
+ == INSTALL:
68
+
69
+ <tt>sudo gem install acts_as_markup</tt>
70
+
71
+ Add "+acts_as_markup+" to your environment.rb:
72
+
73
+ config.gem "acts_as_markup"
74
+
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ # Look in the tasks/setup.rb file for the various options that can be
2
+ # configured in this Rakefile. The .rake files in the tasks directory
3
+ # are where the options are used.
4
+
5
+ load 'tasks/setup.rb'
6
+
7
+ ensure_in_path 'lib'
8
+ require 'acts_as_markup'
9
+
10
+ task :default => 'test:run'
11
+
12
+ PROJ.name = 'acts_as_markup'
13
+ PROJ.authors = 'Brian Landau'
14
+ PROJ.email = 'brian.landau@viget.com'
15
+ PROJ.url = 'http://viget.rubyforge.com/acts_as_markup'
16
+ PROJ.description = "Represent ActiveRecord Markdown or Textile text columns as Markdown or Textile objects using various external libraries to convert to HTML."
17
+ PROJ.rubyforge.name = 'viget'
18
+ PROJ.version = ActsAsMarkup::VERSION
19
+ PROJ.rdoc.include = %w(^lib/ LICENSE\.txt README\.rdoc)
20
+ PROJ.rdoc.remote_dir = 'acts_as_markup'
21
+ PROJ.test.files = FileList['test/**/*_test.rb']
22
+
23
+ %W(activesupport activerecord rdiscount redcloth).each do |gem|
24
+ depend_on gem
25
+ end
@@ -0,0 +1,42 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{acts_as_markup}
3
+ s.version = "0.1.0"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["Brian Landau"]
7
+ s.date = %q{2008-08-06}
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
+ s.email = %q{brian.landau@viget.com}
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"]
12
+ s.has_rdoc = true
13
+ s.homepage = %q{http://viget.rubyforge.com/acts_as_markup}
14
+ s.rdoc_options = ["--main", "README.rdoc"]
15
+ s.require_paths = ["lib"]
16
+ s.rubyforge_project = %q{viget}
17
+ s.rubygems_version = %q{1.2.0}
18
+ s.summary = %q{Represent ActiveRecord Markdown or Textile text columns as Markdown or Textile objects using various external libraries to convert to HTML}
19
+ s.test_files = ["test/acts_as_markup_test.rb"]
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 2
24
+
25
+ if current_version >= 3 then
26
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.1.0"])
27
+ s.add_runtime_dependency(%q<activerecord>, [">= 2.1.0"])
28
+ s.add_runtime_dependency(%q<rdiscount>, [">= 1.2.7"])
29
+ s.add_runtime_dependency(%q<redcloth>, [">= 0"])
30
+ else
31
+ s.add_dependency(%q<activesupport>, [">= 2.1.0"])
32
+ s.add_dependency(%q<activerecord>, [">= 2.1.0"])
33
+ s.add_dependency(%q<rdiscount>, [">= 1.2.7"])
34
+ s.add_dependency(%q<redcloth>, [">= 0"])
35
+ end
36
+ else
37
+ s.add_dependency(%q<activesupport>, [">= 2.1.0"])
38
+ s.add_dependency(%q<activerecord>, [">= 2.1.0"])
39
+ s.add_dependency(%q<rdiscount>, [">= 1.2.7"])
40
+ s.add_dependency(%q<redcloth>, [">= 0"])
41
+ end
42
+ end
@@ -0,0 +1,74 @@
1
+ require 'active_record'
2
+
3
+ module ActiveRecord # :nodoc:
4
+ module Acts # :nodoc:
5
+ module AsMarkup
6
+ def self.included(base) # :nodoc:
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ ##
13
+ # This allows you to specify columns you want to define as containing
14
+ # Markdown or Textile content.
15
+ # Then you can simply call <tt>.to_html</tt> method on the attribute.
16
+ #
17
+ # ==== Example
18
+ # class Post < ActiveRecrod
19
+ # acts_as_markup :language => :markdown, :columns => [:body]
20
+ # end
21
+ #
22
+ # @post = Post.find(:first)
23
+ # @post.body.to_s #=> "## Markdown Headline"
24
+ # @post.body.to_html #=> "<h2> Markdown Headline</h2>"
25
+ #
26
+ def acts_as_markup(options)
27
+ case options[:language].to_sym
28
+ when :markdown
29
+ library_names = ::ActsAsMarkup::MARKDOWN_LIBS[ActsAsMarkup.markdown_library]
30
+ require library_names[:lib_name]
31
+ klass = library_names[:class_name]
32
+ when :textile
33
+ require 'redcloth'
34
+ klass = 'RedCloth'
35
+ else
36
+ raise ActsAsMarkup::UnsportedMarkupLanguage, "#{options[:langauge]} is not a currently supported markup language."
37
+ end
38
+
39
+ 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}
45
+ end
46
+ end
47
+ @#{col.to_s} = #{klass}.new(self['#{col.to_s}'].to_s)
48
+ end
49
+ EOV
50
+ end
51
+ end
52
+
53
+ ##
54
+ # This is a convenience method for
55
+ # `<tt>acts_as_markup :language => :markdown, :columns => [:body]</tt>`
56
+ #
57
+ def acts_as_markdown(*columns)
58
+ acts_as_markup :language => :markdown, :columns => columns
59
+ end
60
+
61
+ ##
62
+ # This is a convenience method for
63
+ # `<tt>acts_as_markup :language => :textile, :columns => [:body]</tt>`
64
+ #
65
+ def acts_as_textile(*columns)
66
+ acts_as_markup :language => :textile, :columns => columns
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ ActiveRecord::Base.send :include, ActiveRecord::Acts::AsMarkup
@@ -0,0 +1,5 @@
1
+ class RDiscount
2
+ def to_s
3
+ self.text
4
+ end
5
+ end
@@ -0,0 +1,66 @@
1
+ require 'active_support'
2
+
3
+ module ActsAsMarkup
4
+ # :stopdoc:
5
+ VERSION = '0.1.0'
6
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
+ # :startdoc:
9
+
10
+ # This exception is raised when an unsupported markup language is supplied to acts_as_markup.
11
+ class UnsportedMarkupLanguage < ArgumentError
12
+ end
13
+
14
+ DEFAULT_MAKRDOWN_LIB = :rdiscount
15
+
16
+ MARKDOWN_LIBS = { :rdiscount => {:class_name => "RDiscount",
17
+ :lib_name => "rdiscount"},
18
+ :bluecloth => {:class_name => "BlueCloth",
19
+ :lib_name => "bluecloth"},
20
+ :rpeg => {:class_name => "PEGMarkdown",
21
+ :lib_name => "peg_markdown"} }
22
+
23
+ @@markdown_library = DEFAULT_MAKRDOWN_LIB
24
+ mattr_accessor :markdown_library
25
+
26
+ # :stopdoc:
27
+ # Returns the version string for the library.
28
+ #
29
+ def self.version
30
+ VERSION
31
+ end
32
+
33
+ # Returns the library path for the module. If any arguments are given,
34
+ # they will be joined to the end of the libray path using
35
+ # <tt>File.join</tt>.
36
+ #
37
+ def self.libpath( *args )
38
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
39
+ end
40
+
41
+ # Returns the lpath for the module. If any arguments are given,
42
+ # they will be joined to the end of the path using
43
+ # <tt>File.join</tt>.
44
+ #
45
+ def self.path( *args )
46
+ args.empty? ? PATH : ::File.join(PATH, *args)
47
+ end
48
+
49
+ # Utility method used to rquire all files ending in .rb that lie in the
50
+ # directory below this file that has the same name as the filename passed
51
+ # in. Optionally, a specific _directory_ name can be passed in such that
52
+ # the _filename_ does not have to be equivalent to the directory.
53
+ #
54
+ def self.require_all_libs_relative_to( fname, dir = nil )
55
+ dir ||= ::File.basename(fname, '.*')
56
+ search_me = ::File.expand_path(
57
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
58
+
59
+ Dir.glob(search_me).sort.each {|rb| require rb}
60
+ end
61
+ # :startdoc:
62
+
63
+ end # module ActsAsMarkup
64
+
65
+ ActsAsMarkup.require_all_libs_relative_to __FILE__
66
+ ActsAsMarkup.require_all_libs_relative_to __FILE__, 'acts'
data/tasks/bones.rake ADDED
@@ -0,0 +1,21 @@
1
+ # $Id$
2
+
3
+ if HAVE_BONES
4
+
5
+ namespace :bones do
6
+
7
+ desc 'Show the PROJ open struct'
8
+ task :debug do |t|
9
+ atr = if t.application.top_level_tasks.length == 2
10
+ t.application.top_level_tasks.pop
11
+ end
12
+
13
+ if atr then Bones::Debug.show_attr(PROJ, atr)
14
+ else Bones::Debug.show PROJ end
15
+ end
16
+
17
+ end # namespace :bones
18
+
19
+ end # HAVE_BONES
20
+
21
+ # EOF
data/tasks/gem.rake ADDED
@@ -0,0 +1,126 @@
1
+ # $Id$
2
+
3
+ require 'rake/gempackagetask'
4
+
5
+ namespace :gem do
6
+
7
+ PROJ.gem._spec = Gem::Specification.new do |s|
8
+ s.name = PROJ.name
9
+ s.version = PROJ.version
10
+ s.summary = PROJ.summary
11
+ s.authors = Array(PROJ.authors)
12
+ s.email = PROJ.email
13
+ s.homepage = Array(PROJ.url).first
14
+ s.rubyforge_project = PROJ.rubyforge.name
15
+
16
+ s.description = PROJ.description
17
+
18
+ PROJ.gem.dependencies.each do |dep|
19
+ s.add_dependency(*dep)
20
+ end
21
+
22
+ s.files = PROJ.gem.files
23
+ s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)}
24
+ s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/
25
+
26
+ s.bindir = 'bin'
27
+ dirs = Dir["{#{PROJ.libs.join(',')}}"]
28
+ s.require_paths = dirs unless dirs.empty?
29
+
30
+ incl = Regexp.new(PROJ.rdoc.include.join('|'))
31
+ excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
32
+ excl = Regexp.new(excl.join('|'))
33
+ rdoc_files = PROJ.gem.files.find_all do |fn|
34
+ case fn
35
+ when excl; false
36
+ when incl; true
37
+ else false end
38
+ end
39
+ s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main]
40
+ s.extra_rdoc_files = rdoc_files
41
+ s.has_rdoc = true
42
+
43
+ if test ?f, PROJ.test.file
44
+ s.test_file = PROJ.test.file
45
+ else
46
+ s.test_files = PROJ.test.files.to_a
47
+ end
48
+
49
+ # Do any extra stuff the user wants
50
+ PROJ.gem.extras.each do |msg, val|
51
+ case val
52
+ when Proc
53
+ val.call(s.send(msg))
54
+ else
55
+ s.send "#{msg}=", val
56
+ end
57
+ end
58
+ end # Gem::Specification.new
59
+
60
+ # A prerequisites task that all other tasks depend upon
61
+ task :prereqs
62
+
63
+ desc 'Show information about the gem'
64
+ task :debug => 'gem:prereqs' do
65
+ puts PROJ.gem._spec.to_ruby
66
+ end
67
+
68
+ pkg = Rake::PackageTask.new(PROJ.name, PROJ.version) do |pkg|
69
+ pkg.need_tar = PROJ.gem.need_tar
70
+ pkg.need_zip = PROJ.gem.need_zip
71
+ pkg.package_files += PROJ.gem._spec.files
72
+ end
73
+ Rake::Task['gem:package'].instance_variable_set(:@full_comment, nil)
74
+
75
+ gem_file = if PROJ.gem._spec.platform == Gem::Platform::RUBY
76
+ "#{pkg.package_name}.gem"
77
+ else
78
+ "#{pkg.package_name}-#{PROJ.gem._spec.platform}.gem"
79
+ end
80
+
81
+ desc "Build the gem file #{gem_file}"
82
+ task :package => ['gem:prereqs', "#{pkg.package_dir}/#{gem_file}"]
83
+
84
+ file "#{pkg.package_dir}/#{gem_file}" => [pkg.package_dir] + PROJ.gem._spec.files do
85
+ when_writing("Creating GEM") {
86
+ Gem::Builder.new(PROJ.gem._spec).build
87
+ verbose(true) {
88
+ mv gem_file, "#{pkg.package_dir}/#{gem_file}"
89
+ }
90
+ }
91
+ end
92
+
93
+ desc 'Install the gem'
94
+ task :install => [:clobber, 'gem:package'] do
95
+ sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
96
+
97
+ # use this version of the command for rubygems > 1.0.0
98
+ #sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}"
99
+ end
100
+
101
+ desc 'Uninstall the gem'
102
+ task :uninstall do
103
+ installed_list = Gem.source_index.find_name(PROJ.name)
104
+ if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then
105
+ sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}"
106
+ end
107
+ end
108
+
109
+ desc 'Reinstall the gem'
110
+ task :reinstall => [:uninstall, :install]
111
+
112
+ desc 'Cleanup the gem'
113
+ task :cleanup do
114
+ sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}"
115
+ end
116
+
117
+ end # namespace :gem
118
+
119
+ desc 'Alias to gem:package'
120
+ task :gem => 'gem:package'
121
+
122
+ task :clobber => 'gem:clobber_package'
123
+
124
+ remove_desc_for_task %w(gem:clobber_package)
125
+
126
+ # EOF