acts_as_markup_extended 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +4 -0
- data/LICENSE +22 -0
- data/README.rdoc +198 -0
- data/Rakefile +35 -0
- data/lib/acts/as_markup.rb +251 -0
- data/lib/acts_as_markup/exts/maruku.rb +70 -0
- data/lib/acts_as_markup/exts/object.rb +1 -0
- data/lib/acts_as_markup/exts/peg_markdown.rb +10 -0
- data/lib/acts_as_markup/exts/rdiscount.rb +15 -0
- data/lib/acts_as_markup/exts/rdoc.rb +101 -0
- data/lib/acts_as_markup/exts/wikitext.rb +20 -0
- data/lib/acts_as_markup/stringlike.rb +7 -0
- data/lib/acts_as_markup_extended.rb +79 -0
- data/lib/markup_extensions.rb +24 -0
- data/lib/markup_methods/ahttp.rb +27 -0
- data/lib/markup_methods/checklist.rb +30 -0
- data/lib/markup_methods/logo.rb +27 -0
- data/test/acts_as_markdown_test.rb +298 -0
- data/test/acts_as_markup_extended.rb +90 -0
- data/test/acts_as_markup_test.rb +593 -0
- data/test/acts_as_rdoc_test.rb +58 -0
- data/test/acts_as_textile_test.rb +77 -0
- data/test/acts_as_wikitext_test.rb +77 -0
- data/test/markup_methods_test.rb +95 -0
- data/test/test_helper.rb +69 -0
- metadata +166 -0
@@ -0,0 +1,70 @@
|
|
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
|
@@ -0,0 +1 @@
|
|
1
|
+
Object.send :alias_method, :to_html, :to_s
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'rdoc/markup/simple_markup'
|
2
|
+
require 'rdoc/markup/simple_markup/to_html'
|
3
|
+
|
4
|
+
class RDocWithHyperlinkToHtml < SM::ToHtml
|
5
|
+
|
6
|
+
# Generate a hyperlink for url, labeled with text. Handle the
|
7
|
+
# special cases for img: and link: described under handle_special_HYPEDLINK
|
8
|
+
#
|
9
|
+
def gen_url(url, text)
|
10
|
+
if url =~ /([A-Za-z]+):(.*)/
|
11
|
+
type = $1
|
12
|
+
path = $2
|
13
|
+
else
|
14
|
+
type = "http"
|
15
|
+
path = url
|
16
|
+
url = "http://#{url}"
|
17
|
+
end
|
18
|
+
|
19
|
+
if type == "link"
|
20
|
+
if path[0,1] == '#' # is this meaningful?
|
21
|
+
url = path
|
22
|
+
else
|
23
|
+
url = HTMLGenerator.gen_url(@from_path, path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if (type == "http" || type == "link") && url =~ /\.(gif|png|jpg|jpeg|bmp)$/
|
28
|
+
"<img src=\"#{url}\" />"
|
29
|
+
else
|
30
|
+
"<a href=\"#{url}\">#{text.sub(%r{^#{type}:/*}, '')}</a>"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# And we're invoked with a potential external hyperlink mailto:
|
35
|
+
# just gets inserted. http: links are checked to see if they
|
36
|
+
# reference an image. If so, that image gets inserted using an
|
37
|
+
# <img> tag. Otherwise a conventional <a href> is used. We also
|
38
|
+
# support a special type of hyperlink, link:, which is a reference
|
39
|
+
# to a local file whose path is relative to the --op directory.
|
40
|
+
#
|
41
|
+
def handle_special_HYPERLINK(special)
|
42
|
+
url = special.text
|
43
|
+
gen_url(url, url)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Here's a hypedlink where the label is different to the URL
|
47
|
+
# <label>[url]
|
48
|
+
#
|
49
|
+
def handle_special_TIDYLINK(special)
|
50
|
+
text = special.text
|
51
|
+
unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/
|
52
|
+
return text
|
53
|
+
end
|
54
|
+
label = $1
|
55
|
+
url = $2
|
56
|
+
gen_url(url, label)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
# This allows a us to create a wrapper object similar to those provided by the
|
62
|
+
# Markdown and Textile libraries. It stores the original and formated HTML text
|
63
|
+
# in instance variables. It also stores the SimpleMarkup parser objects in
|
64
|
+
# instance variables.
|
65
|
+
#
|
66
|
+
class RDocText < String
|
67
|
+
attr_reader :text
|
68
|
+
attr_reader :html
|
69
|
+
attr_reader :markup
|
70
|
+
attr_reader :html_formater
|
71
|
+
|
72
|
+
def initialize(str)
|
73
|
+
super(str)
|
74
|
+
@text = str.to_s
|
75
|
+
@markup = SM::SimpleMarkup.new
|
76
|
+
|
77
|
+
# external hyperlinks
|
78
|
+
@markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)
|
79
|
+
|
80
|
+
# and links of the form <text>[<url>]
|
81
|
+
@markup.add_special(/(((\{.*?\})|\b\S+?)\[\S+?\.\S+?\])/, :TIDYLINK)
|
82
|
+
|
83
|
+
# Convert leading comment markers to spaces, but only
|
84
|
+
# if all non-blank lines have them
|
85
|
+
|
86
|
+
if str =~ /^(?>\s*)[^\#]/
|
87
|
+
content = str
|
88
|
+
else
|
89
|
+
content = str.gsub(/^\s*(#+)/) { $1.tr('#',' ') }
|
90
|
+
end
|
91
|
+
|
92
|
+
@html_formatter = RDocWithHyperlinkToHtml.new
|
93
|
+
|
94
|
+
@html = @markup.convert(@text, @html_formatter)
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_html
|
98
|
+
@html
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'wikitext'
|
2
|
+
|
3
|
+
# This allows a us to create a wrapper object similar to those provided by the
|
4
|
+
# Markdown and Textile libraries. It stores the original and formated HTML text
|
5
|
+
# in instance variables.
|
6
|
+
#
|
7
|
+
class WikitextString < String
|
8
|
+
attr_reader :text
|
9
|
+
attr_reader :html
|
10
|
+
|
11
|
+
def initialize(str, *options)
|
12
|
+
super(str)
|
13
|
+
@text = str.to_s
|
14
|
+
@html = Wikitext::Parser.new(*options).parse(@text)
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_html
|
18
|
+
@html
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
|
5
|
+
module ActsAsMarkup
|
6
|
+
# :stopdoc:
|
7
|
+
VERSION = '1.3.4'.freeze
|
8
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
9
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
10
|
+
# :startdoc:
|
11
|
+
|
12
|
+
# This exception is raised when an unsupported markup language is supplied to acts_as_markup.
|
13
|
+
class UnsupportedMarkupLanguage < ArgumentError
|
14
|
+
end
|
15
|
+
# This exception is raised when an unsupported Markdown library is set to the config value.
|
16
|
+
class UnsportedMarkdownLibrary < ArgumentError
|
17
|
+
end
|
18
|
+
# this extension is raised when an extension method doesn't exist
|
19
|
+
class UnknownExtensionMethod < ArgumentError
|
20
|
+
end
|
21
|
+
DEFAULT_MARKDOWN_LIB = :rdiscount
|
22
|
+
|
23
|
+
MARKDOWN_LIBS = { :rdiscount => {:class_name => "RDiscount",
|
24
|
+
:lib_name => "rdiscount"},
|
25
|
+
:bluecloth => {:class_name => "BlueCloth",
|
26
|
+
:lib_name => "bluecloth"},
|
27
|
+
:rpeg => {:class_name => "PEGMarkdown",
|
28
|
+
:lib_name => "peg_markdown"},
|
29
|
+
:maruku => {:class_name => "Maruku",
|
30
|
+
:lib_name => "maruku"} }
|
31
|
+
|
32
|
+
LIBRARY_EXTENSIONS = ::Set.new(Dir[ActsAsMarkup::LIBPATH + 'acts_as_markup/exts/*.rb'].map {|file| File.basename(file, '.rb')}).delete('string')
|
33
|
+
|
34
|
+
@@markdown_library = DEFAULT_MARKDOWN_LIB
|
35
|
+
mattr_accessor :markdown_library
|
36
|
+
|
37
|
+
# :stopdoc:
|
38
|
+
# Returns the version string for the library.
|
39
|
+
#
|
40
|
+
def self.version
|
41
|
+
VERSION
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the library path for the module. If any arguments are given,
|
45
|
+
# they will be joined to the end of the library path using
|
46
|
+
# <tt>File.join</tt>.
|
47
|
+
#
|
48
|
+
def self.libpath( *args )
|
49
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the path for the module. If any arguments are given,
|
53
|
+
# they will be joined to the end of the path using
|
54
|
+
# <tt>File.join</tt>.
|
55
|
+
#
|
56
|
+
def self.path( *args )
|
57
|
+
args.empty? ? PATH : ::File.join(PATH, *args)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Utility method used to rquire all files ending in .rb that lie in the
|
61
|
+
# directory below this file that has the same name as the filename passed
|
62
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
63
|
+
# the _filename_ does not have to be equivalent to the directory.
|
64
|
+
#
|
65
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
66
|
+
dir ||= ::File.basename(fname, '.*')
|
67
|
+
search_me = ::File.expand_path(
|
68
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
69
|
+
|
70
|
+
Dir.glob(search_me).sort.each {|rb| require rb}
|
71
|
+
end
|
72
|
+
# :startdoc:
|
73
|
+
|
74
|
+
end # module ActsAsMarkup
|
75
|
+
|
76
|
+
require 'acts_as_markup/exts/object'
|
77
|
+
require 'acts_as_markup/stringlike'
|
78
|
+
require 'markup_extensions'
|
79
|
+
ActsAsMarkup.require_all_libs_relative_to __FILE__, 'acts'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
ActsAsMarkup.require_all_libs_relative_to __FILE__, 'markup_methods'
|
2
|
+
ActsAsMarkup.require_all_libs_relative_to "lib/.", 'markup_methods'
|
3
|
+
|
4
|
+
module MarkupExtensions
|
5
|
+
class MString < String
|
6
|
+
include MarkupExtensionMethods
|
7
|
+
|
8
|
+
def run_methods(methods)
|
9
|
+
(methods == :all ?
|
10
|
+
MarkupExtensionMethods.instance_methods :
|
11
|
+
methods
|
12
|
+
).inject(self) { |mstring, meth|
|
13
|
+
if mstring.respond_to? meth
|
14
|
+
MString.new(mstring.send(meth))
|
15
|
+
else
|
16
|
+
raise ActsAsMarkup::UnknownExtensionMethod,
|
17
|
+
"Extension method \"#{meth.to_s}\" is not defined "
|
18
|
+
MString.new(mstring)
|
19
|
+
end
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MarkupExtensionMethods
|
2
|
+
|
3
|
+
# This sample extension replaces URL strings in the form:
|
4
|
+
# "http://..."
|
5
|
+
# with links:
|
6
|
+
# "<a href="http://..."
|
7
|
+
#
|
8
|
+
# Strings that are already part of
|
9
|
+
# <a href= ...> or <img src= ...>
|
10
|
+
# or inside
|
11
|
+
# <code> or <pre>
|
12
|
+
# tags will remain unchanged
|
13
|
+
#
|
14
|
+
# (This extension can be used for any markup language.)
|
15
|
+
#
|
16
|
+
def ahttp
|
17
|
+
gsub( /http:\/\/[^\s><"']+/ ) {
|
18
|
+
match = $&; before = $`; after = $'
|
19
|
+
before !~ /\s+(href|src|)\s*=\s*['"]*$/ &&
|
20
|
+
after !~ /^[^<]*<\/a>/ &&
|
21
|
+
before !~ /(<code>|<pre>).*$/ ?
|
22
|
+
%Q~<a href="#{match}">#{match}</a>~ :
|
23
|
+
match
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MarkupExtensionMethods
|
2
|
+
|
3
|
+
# This sample extension allows list elements to act as a checklist.
|
4
|
+
# If the markup list indicator is followed by a disposition character
|
5
|
+
# and a space, this method will make checklist substitutions.
|
6
|
+
#
|
7
|
+
# For example, when this method sees this in a Markdown list:
|
8
|
+
# '- x item one'
|
9
|
+
# or this in a Textile list:
|
10
|
+
# '* x item one"
|
11
|
+
# it will substitute:
|
12
|
+
# '<li <strong>(x)</strong> item one'.
|
13
|
+
#
|
14
|
+
# This method recognizes these disposition characters.
|
15
|
+
# x - item completed
|
16
|
+
# 0 - item dropped
|
17
|
+
# d - item deferred
|
18
|
+
# @ - item in progress
|
19
|
+
#
|
20
|
+
# (this extension can be used for any markup language.)
|
21
|
+
#
|
22
|
+
def checklist
|
23
|
+
gsub(/<li>([x0d@]) (\S)/) {
|
24
|
+
m1 = $1;m2 = $2
|
25
|
+
m1 = ">" if m1 == "d"
|
26
|
+
"<li><strong>(#{m1.upcase}) </strong>#{m2}"
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MarkupExtensionMethods
|
2
|
+
|
3
|
+
# This sample extension inserts a company logo.
|
4
|
+
# If Markdown contains:
|
5
|
+
# "[logo](home)"
|
6
|
+
# or Textile contains:
|
7
|
+
# "logo":home
|
8
|
+
# The generated HTML contains the company logo and links to the home page.
|
9
|
+
#
|
10
|
+
# (This extension can be used for any markup language)
|
11
|
+
#
|
12
|
+
def logo
|
13
|
+
gsub( /<a href="home">logo<\/a>/ ) {
|
14
|
+
match = $&; before = $`
|
15
|
+
if before !~ /(<code>|<pre>).*$/
|
16
|
+
%Q~<a href="http://www.google.com">\n~ +
|
17
|
+
%Q~<img id="logo" alt="Google"~ +
|
18
|
+
%Q~ src="http://www.google.com/images/logos/google_logo.gif"~ +
|
19
|
+
%Q~ style="border: 0 none;">\n~ +
|
20
|
+
%Q~</a>\n~
|
21
|
+
else
|
22
|
+
match
|
23
|
+
end
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,298 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class ActsAsMarkdownTest < ActsAsMarkupTestCase
|
4
|
+
context 'acts_as_markdown' do
|
5
|
+
setup do
|
6
|
+
@markdown_text = '## Markdown Test Text'
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'using RDiscount' do
|
10
|
+
setup do
|
11
|
+
ActsAsMarkup.markdown_library = :rdiscount
|
12
|
+
class ::Post < ActiveRecord::Base
|
13
|
+
acts_as_markdown :body
|
14
|
+
end
|
15
|
+
@post = Post.create!(:title => 'Blah', :body => @markdown_text)
|
16
|
+
end
|
17
|
+
|
18
|
+
should_act_like_a_string
|
19
|
+
|
20
|
+
should "have a RDiscount object returned for the column value" do
|
21
|
+
assert_kind_of RDiscount, @post.body
|
22
|
+
end
|
23
|
+
|
24
|
+
should "return original markdown text for a `to_s` method call on the column value" do
|
25
|
+
assert_equal @markdown_text, @post.body.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
should 'return false for .blank?' do
|
29
|
+
assert !@post.body.blank?
|
30
|
+
end
|
31
|
+
|
32
|
+
should "return formatted html for a `to_html` method call on the column value" do
|
33
|
+
assert_match(/<h2(\s\w+\=['"]\w*['"])*\s*>\s*Markdown Test Text\s*<\/h2>/, @post.body.to_html)
|
34
|
+
end
|
35
|
+
|
36
|
+
should "not return escaped html" do
|
37
|
+
@post.body = "## Markdown <i>Test</i> Text"
|
38
|
+
assert_match(/<i>Test<\/i>/, @post.body.to_html)
|
39
|
+
end
|
40
|
+
|
41
|
+
context "changing value of markdown field should return new markdown object" do
|
42
|
+
setup do
|
43
|
+
@old_body = @post.body
|
44
|
+
@post.body = "`@count = 20`"
|
45
|
+
end
|
46
|
+
|
47
|
+
should "still have an RDiscount object but not the same object" do
|
48
|
+
assert_kind_of RDiscount, @post.body
|
49
|
+
assert_not_same @post.body, @old_body
|
50
|
+
end
|
51
|
+
|
52
|
+
should "return correct text for `to_s`" do
|
53
|
+
assert_equal "`@count = 20`", @post.body.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
should "return correct HTML for the `to_html` method" do
|
57
|
+
assert_match(/<code>\s*\@count\s\=\s20\s*<\/code>/, @post.body.to_html)
|
58
|
+
end
|
59
|
+
|
60
|
+
teardown do
|
61
|
+
@old_body = nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
teardown do
|
66
|
+
@post = nil
|
67
|
+
Post.delete_all
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'using RDiscount with options' do
|
72
|
+
setup do
|
73
|
+
class ::Post
|
74
|
+
acts_as_markdown :body, :markdown_options => [ :filter_html ]
|
75
|
+
end
|
76
|
+
@post = Post.new(:title => 'Blah')
|
77
|
+
end
|
78
|
+
|
79
|
+
should "return escaped html because of :filter_html" do
|
80
|
+
@post.body = "## Markdown <i>Test</i> Text"
|
81
|
+
assert_match(/<i>Test<\/i>/, @post.body.to_html)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'using Ruby PEG Markdown' do
|
86
|
+
setup do
|
87
|
+
ActsAsMarkup.markdown_library = :rpeg
|
88
|
+
class ::Post < ActiveRecord::Base
|
89
|
+
acts_as_markdown :body
|
90
|
+
end
|
91
|
+
@post = Post.create!(:title => 'Blah', :body => @markdown_text)
|
92
|
+
end
|
93
|
+
|
94
|
+
should_act_like_a_string
|
95
|
+
|
96
|
+
should "have a Ruby PEG Markdown object returned for the column value" do
|
97
|
+
assert_kind_of PEGMarkdown, @post.body
|
98
|
+
end
|
99
|
+
|
100
|
+
should "return original markdown text for a `to_s` method call on the column value" do
|
101
|
+
assert_equal @markdown_text, @post.body.to_s
|
102
|
+
end
|
103
|
+
|
104
|
+
should 'return false for .blank?' do
|
105
|
+
assert !@post.body.blank?
|
106
|
+
end
|
107
|
+
|
108
|
+
should "return formated html for a `to_html` method call on the column value" do
|
109
|
+
assert_match(/<h2(\s\w+\=['"]\w*['"])*\s*>\s*Markdown Test Text\s*<\/h2>/, @post.body.to_html)
|
110
|
+
end
|
111
|
+
|
112
|
+
should "not return escaped html" do
|
113
|
+
@post.body = "## Markdown <i>Test</i> Text"
|
114
|
+
assert_match(/<i>Test<\/i>/, @post.body.to_html)
|
115
|
+
end
|
116
|
+
|
117
|
+
context "changing value of markdown field should return new markdown object" do
|
118
|
+
setup do
|
119
|
+
@old_body = @post.body
|
120
|
+
@post.body = "`@count = 20`"
|
121
|
+
end
|
122
|
+
|
123
|
+
should "still have an PEGMarkdown object but not the same object" do
|
124
|
+
assert_kind_of PEGMarkdown, @post.body
|
125
|
+
assert_not_same @post.body, @old_body
|
126
|
+
end
|
127
|
+
|
128
|
+
should "return correct text for `to_s`" do
|
129
|
+
assert_equal "`@count = 20`", @post.body.to_s
|
130
|
+
end
|
131
|
+
|
132
|
+
should "return correct HTML for the `to_html` method" do
|
133
|
+
assert_match(/<code>\s*\@count\s\=\s20\s*<\/code>/, @post.body.to_html)
|
134
|
+
end
|
135
|
+
|
136
|
+
teardown do
|
137
|
+
@old_body = nil
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
teardown do
|
142
|
+
@post = nil
|
143
|
+
Post.delete_all
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'using Ruby PEG Markdown with options' do
|
148
|
+
setup do
|
149
|
+
class ::Post
|
150
|
+
acts_as_markdown :body, :markdown_options => [ :filter_html ]
|
151
|
+
end
|
152
|
+
@post = Post.new(:title => 'Blah')
|
153
|
+
end
|
154
|
+
|
155
|
+
should "return no html because of :filter_html" do
|
156
|
+
@post.body = "## Markdown <i>Test</i> Text"
|
157
|
+
assert_match(/Markdown Test Text/, @post.body.to_html)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'using BlueCloth' do
|
162
|
+
setup do
|
163
|
+
ActsAsMarkup.markdown_library = :bluecloth
|
164
|
+
class ::Post < ActiveRecord::Base
|
165
|
+
acts_as_markdown :body
|
166
|
+
end
|
167
|
+
@post = Post.create!(:title => 'Blah', :body => @markdown_text)
|
168
|
+
end
|
169
|
+
|
170
|
+
should_act_like_a_string
|
171
|
+
|
172
|
+
should "have a BlueCloth object returned for the column value" do
|
173
|
+
assert_kind_of BlueCloth, @post.body
|
174
|
+
end
|
175
|
+
|
176
|
+
should "return original markdown text for a `to_s` method call on the column value" do
|
177
|
+
assert_equal @markdown_text, @post.body.to_s
|
178
|
+
end
|
179
|
+
|
180
|
+
should 'return false for .blank?' do
|
181
|
+
assert !@post.body.blank?
|
182
|
+
end
|
183
|
+
|
184
|
+
should "return formated html for a `to_html` method call on the column value" do
|
185
|
+
assert_match(/<h2(\s\w+\=['"]\w*['"])*\s*>\s*Markdown Test Text\s*<\/h2>/, @post.body.to_html)
|
186
|
+
end
|
187
|
+
|
188
|
+
should "not return escaped html" do
|
189
|
+
@post.body = "## Markdown <i>Test</i> Text"
|
190
|
+
assert_match(/<i>Test<\/i>/, @post.body.to_html)
|
191
|
+
end
|
192
|
+
|
193
|
+
context "changing value of markdown field should return new markdown object" do
|
194
|
+
setup do
|
195
|
+
@old_body = @post.body
|
196
|
+
@post.body = "`@count = 20`"
|
197
|
+
end
|
198
|
+
|
199
|
+
should "still have an BlueCloth object but not the same object" do
|
200
|
+
assert_kind_of BlueCloth, @post.body
|
201
|
+
assert_not_same @post.body, @old_body
|
202
|
+
end
|
203
|
+
|
204
|
+
should "return correct text for `to_s`" do
|
205
|
+
assert_equal "`@count = 20`", @post.body.to_s
|
206
|
+
end
|
207
|
+
|
208
|
+
should "return correct HTML for the `to_html` method" do
|
209
|
+
assert_match(/<code>\s*\@count\s\=\s20\s*<\/code>/, @post.body.to_html)
|
210
|
+
end
|
211
|
+
|
212
|
+
teardown do
|
213
|
+
@old_body = nil
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
teardown do
|
218
|
+
@post = nil
|
219
|
+
Post.delete_all
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'using BlueCloth with options' do
|
224
|
+
setup do
|
225
|
+
class ::Post
|
226
|
+
acts_as_markdown :body, :markdown_options => [ :filter_html ]
|
227
|
+
end
|
228
|
+
@post = Post.new(:title => 'Blah')
|
229
|
+
end
|
230
|
+
|
231
|
+
should "return escaped html because of :filter_html" do
|
232
|
+
@post.body = "## Markdown <i>Test</i> Text"
|
233
|
+
assert_match(/<i>Test<\/i>/, @post.body.to_html)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context 'using Maruku' do
|
238
|
+
setup do
|
239
|
+
ActsAsMarkup.markdown_library = :maruku
|
240
|
+
class ::Post < ActiveRecord::Base
|
241
|
+
acts_as_markdown :body
|
242
|
+
end
|
243
|
+
@post = Post.create!(:title => 'Blah', :body => @markdown_text)
|
244
|
+
end
|
245
|
+
|
246
|
+
should_act_like_a_string
|
247
|
+
|
248
|
+
should "have a Maruku object returned for the column value" do
|
249
|
+
assert_kind_of Maruku, @post.body
|
250
|
+
end
|
251
|
+
|
252
|
+
should "return original markdown text for a `to_s` method call on the column value" do
|
253
|
+
assert_equal @markdown_text, @post.body.to_s
|
254
|
+
end
|
255
|
+
|
256
|
+
should 'return false for .blank?' do
|
257
|
+
assert !@post.body.blank?
|
258
|
+
end
|
259
|
+
|
260
|
+
should "return formated html for a `to_html` method call on the column value" do
|
261
|
+
assert_match(/<h2(\s\w+\=['"]\w*['"])*\s*>\s*Markdown Test Text\s*<\/h2>/, @post.body.to_html)
|
262
|
+
end
|
263
|
+
|
264
|
+
context "changing value of markdown field should return new markdown object" do
|
265
|
+
setup do
|
266
|
+
@old_body = @post.body
|
267
|
+
@post.body = "`@count = 20`"
|
268
|
+
end
|
269
|
+
|
270
|
+
should "still have an Maruku object but not the same object" do
|
271
|
+
assert_kind_of Maruku, @post.body
|
272
|
+
assert_not_same @post.body, @old_body
|
273
|
+
end
|
274
|
+
|
275
|
+
should "return correct text for `to_s`" do
|
276
|
+
assert_equal "`@count = 20`", @post.body.to_s
|
277
|
+
end
|
278
|
+
|
279
|
+
should "return correct HTML for the `to_html` method" do
|
280
|
+
assert_match(/<code>\s*\@count\s\=\s20\s*<\/code>/, @post.body.to_html)
|
281
|
+
end
|
282
|
+
|
283
|
+
teardown do
|
284
|
+
@old_body = nil
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
teardown do
|
289
|
+
@post = nil
|
290
|
+
Post.delete_all
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
teardown do
|
295
|
+
@markdown_text = nil
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|