mcbean 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +3 -2
- data/CHANGELOG.rdoc +24 -1
- data/Manifest.txt +2 -1
- data/README.rdoc +32 -24
- data/Rakefile +6 -9
- data/bin/mcbean +57 -4
- data/lib/mcbean.rb +58 -12
- data/lib/mcbean/markdown.rb +37 -6
- data/lib/mcbean/textile.rb +110 -0
- data/test/helper.rb +1 -7
- data/test/test_markdown.rb +138 -99
- data/test/test_mcbean.rb +47 -33
- data/test/test_textile.rb +151 -0
- metadata +31 -43
- metadata.gz.sig +0 -0
- data/History.txt +0 -6
data.tar.gz.sig
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
W�BB�����90���\֫5�#�$Kߵ�2�f�F�ko��%�s��c���
|
2
|
+
n���%�I0?-���aI�j@�hkjo��k��ҷA�j��±�I�?b6Ïw�{�VK9P�:��u�-��~�C��n�g�yeΪ��Z�Lr�.��� ���>E��ښ�Ҝ��k�CZ�F�!/���=N���k܁��+�t��x�먊<e�w)
|
3
|
+
�j���%
|
data/CHANGELOG.rdoc
CHANGED
@@ -2,10 +2,33 @@
|
|
2
2
|
|
3
3
|
== HEAD
|
4
4
|
|
5
|
+
Features:
|
6
|
+
|
7
|
+
* Support for Textile.
|
8
|
+
* McBean#to_html now does the right thing when the instance is created via McBean.markdown or McBean.textile.
|
9
|
+
* McBean#to_html now entity-escapes unsafe and invalid HTML tags (thanks to Loofah).
|
10
|
+
|
11
|
+
Deprecations:
|
12
|
+
|
13
|
+
* McBean.new and .allocate are now private. You shouldn't have been using them, anyway.
|
14
|
+
* McBean#html and #markdown accessors have been dropped.
|
15
|
+
|
16
|
+
== 0.2.0 (2010-03-24)
|
17
|
+
|
18
|
+
* Converts Markdown to HTML (thanks to RDiscount). GH #2.
|
5
19
|
* <br> elements are converted into newlines (markdown). GH #5
|
6
20
|
* <a> elements without an 'href' attribute are not rendered as hyperlinks (markdown). GH #4
|
7
21
|
|
22
|
+
== 0.1.2 (2010-03-10)
|
23
|
+
|
24
|
+
* Command line utility "mcbean"
|
25
|
+
* Demo site on Heroku
|
26
|
+
|
27
|
+
== 0.1.1 (2010-03-09)
|
28
|
+
|
29
|
+
* Better hyperlink handling
|
30
|
+
|
8
31
|
== 0.1.0 (2010-03-09)
|
9
32
|
|
10
33
|
* Happy Birthday!
|
11
|
-
* Converts HTML documents
|
34
|
+
* Converts HTML documents to Markdown.
|
data/Manifest.txt
CHANGED
data/README.rdoc
CHANGED
@@ -1,46 +1,51 @@
|
|
1
1
|
= McBean
|
2
2
|
|
3
3
|
* http://github.com/flavorjones/mcbean
|
4
|
-
* http://mcbean.heroku.com
|
4
|
+
* http://mcbean.heroku.com (live demo)
|
5
5
|
|
6
6
|
== Description
|
7
7
|
|
8
|
-
McBean
|
9
|
-
help of Loofah, Nokogiri and RDiscount).
|
8
|
+
McBean can convert documents from one format to another. McBean currently supports:
|
10
9
|
|
11
|
-
|
12
|
-
Markdown
|
13
|
-
|
14
|
-
of Sneetchy document formats.
|
10
|
+
* HTML
|
11
|
+
* Markdown (a subset)
|
12
|
+
* Textile (a subset)
|
15
13
|
|
16
|
-
|
14
|
+
with the help of Loofah, Nokogiri, RDiscount and RedCloth.
|
17
15
|
|
18
|
-
|
16
|
+
"You can't teach a Sneetch." -- Sylvester McMonkey McBean
|
19
17
|
|
20
|
-
|
21
|
-
* Doesn't do anything else yet.
|
18
|
+
== Features
|
22
19
|
|
23
|
-
|
20
|
+
* Transforms HTML into Markdown, and Markdown into HTML (thanks to RDiscount).
|
21
|
+
* Transforms HTML into Textile, and Textile into HTML (thanks to RedCloth).
|
22
|
+
* Transforms Textile into Markdown, and Markdown into Textile.
|
23
|
+
* Emitted HTML is sanitized (thanks to Loofah).
|
24
|
+
* Fancy-pants command line utility, "mcbean".
|
24
25
|
|
25
|
-
|
26
|
+
== Problems
|
26
27
|
|
27
|
-
|
28
|
+
* Only supports a limited subset of Markdown and Textile. Patches welcome.
|
28
29
|
|
29
|
-
|
30
|
+
== Synopsis
|
30
31
|
|
31
|
-
|
32
|
+
Wrap your document (which can be either a String or an IO object):
|
32
33
|
|
33
|
-
|
34
|
+
mcbean = McBean.fragment(your_html_fragment)
|
35
|
+
mcbean = McBean.document(your_html_document)
|
36
|
+
mcbean = McBean.markdown(your_markdown)
|
37
|
+
mcbean = McBean.textile(your_textile)
|
34
38
|
|
35
|
-
|
39
|
+
And then generate the desired markup format:
|
36
40
|
|
37
|
-
|
38
|
-
|
41
|
+
mcbean.to_html
|
42
|
+
mcbean.to_markdown
|
43
|
+
mcbean.to_textile
|
39
44
|
|
40
45
|
Also, +mcbean+ provides a command-line utility installed into your gem path:
|
41
46
|
|
42
|
-
$ mcbean /
|
43
|
-
$ mcbean
|
47
|
+
$ mcbean --html="http://en.wikipedia.org/wiki/The_Sneetches_and_Other_Stories" --to-markdown
|
48
|
+
$ mcbean --markdown="treetop-1.4.2/doc/grammar_composition.markdown" --to-textile
|
44
49
|
|
45
50
|
You can try out McBean at the live demo site: http://mcbean.heroku.com
|
46
51
|
|
@@ -52,8 +57,9 @@ have a single root node, you have a *fragment*.
|
|
52
57
|
|
53
58
|
== Requirements
|
54
59
|
|
55
|
-
* Loofah 0.4.7 (and thusly Nokogiri)
|
56
|
-
* RDiscount 1.3.4
|
60
|
+
* Loofah >= 0.4.7 (and thusly Nokogiri)
|
61
|
+
* RDiscount >= 1.3.4
|
62
|
+
* RedCloth >= 4.0.0
|
57
63
|
|
58
64
|
== Install
|
59
65
|
|
@@ -63,6 +69,8 @@ have a single root node, you have a *fragment*.
|
|
63
69
|
|
64
70
|
Thanks to David Loren Parsons and Ryan Tomayko for RDiscount.
|
65
71
|
|
72
|
+
Thanks to Jason Garber for RedCloth.
|
73
|
+
|
66
74
|
== License
|
67
75
|
|
68
76
|
(The MIT License)
|
data/Rakefile
CHANGED
@@ -13,10 +13,12 @@ Hoe.spec 'mcbean' do
|
|
13
13
|
self.history_file = "CHANGELOG.rdoc"
|
14
14
|
self.readme_file = "README.rdoc"
|
15
15
|
|
16
|
-
extra_deps << ["loofah", ">= 0.4.7"]
|
17
|
-
extra_deps << ["rdiscount", ">= 1.3.4"]
|
18
|
-
|
19
|
-
extra_dev_deps << ["
|
16
|
+
self.extra_deps << ["loofah", ">= 0.4.7"]
|
17
|
+
self.extra_deps << ["rdiscount", ">= 1.3.4"]
|
18
|
+
self.extra_deps << ["RedCloth", ">= 4.0.0"]
|
19
|
+
self.extra_dev_deps << ["minitest", ">= 1.6.0"]
|
20
|
+
|
21
|
+
self.testlib = :minitest
|
20
22
|
end
|
21
23
|
|
22
24
|
task :redocs => :fix_css
|
@@ -35,11 +37,6 @@ task :fix_css do
|
|
35
37
|
margin-top : .5em ;
|
36
38
|
}
|
37
39
|
|
38
|
-
#main ul, div#documentation ul {
|
39
|
-
list-style-type : disc ! IMPORTANT ;
|
40
|
-
list-style-position : inside ! IMPORTANT ;
|
41
|
-
}
|
42
|
-
|
43
40
|
h2 + ul {
|
44
41
|
margin-top : 1em;
|
45
42
|
}
|
data/bin/mcbean
CHANGED
@@ -3,12 +3,65 @@
|
|
3
3
|
require 'open-uri'
|
4
4
|
require 'rubygems'
|
5
5
|
require 'mcbean'
|
6
|
+
require 'getoptlong'
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
SCRIPT = File.basename(__FILE__)
|
9
|
+
@input_format = "html"
|
10
|
+
@output_format = "markdown"
|
11
|
+
@input_file = nil
|
12
|
+
|
13
|
+
OPTS = []
|
14
|
+
McBean.formats.each do |format|
|
15
|
+
OPTS << [ "--#{format}", "-#{format[0,1]}", GetoptLong::REQUIRED_ARGUMENT ]
|
16
|
+
OPTS << [ "--to-#{format}", "-#{format[0,1].upcase}", GetoptLong::NO_ARGUMENT ]
|
17
|
+
end
|
18
|
+
|
19
|
+
def _usage
|
20
|
+
puts "USAGE: #{SCRIPT} [--<FROM_FORMAT>=]<FILE-OR-URL> [--to-<TO_FORMAT>]"
|
21
|
+
puts
|
22
|
+
puts " McBean transforms a file from one format to another, for your reading pleasure."
|
23
|
+
puts
|
24
|
+
puts " e.g.:"
|
25
|
+
puts " #{SCRIPT} --html=\"http://en.wikipedia.org/wiki/The_Sneetches_and_Other_Stories\" --to-markdown"
|
26
|
+
puts " #{SCRIPT} --markdown=\"sneetches.md\" --to-textile"
|
27
|
+
puts
|
28
|
+
puts " If FROM_FORMAT option is not specified, --#{@input_format} is assumed"
|
29
|
+
puts " If TO_FORMAT option is not specified, --to-#{@output_format} is assumed"
|
9
30
|
puts
|
10
|
-
puts "
|
31
|
+
puts " Shortcuts / Supported Formats:"
|
32
|
+
OPTS.each do |long, short, _|
|
33
|
+
puts " #{short} for #{long}"
|
34
|
+
end
|
11
35
|
exit 1
|
12
36
|
end
|
13
37
|
|
14
|
-
|
38
|
+
begin
|
39
|
+
GetoptLong.new(*OPTS).each do |opt, arg|
|
40
|
+
McBean.formats.each do |format|
|
41
|
+
if opt == "--#{format}"
|
42
|
+
@input_format = format
|
43
|
+
@input_file = arg
|
44
|
+
elsif opt == "--to-#{format}"
|
45
|
+
@output_format = format
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rescue
|
50
|
+
_usage
|
51
|
+
end
|
52
|
+
|
53
|
+
if @input_file.nil?
|
54
|
+
_usage if ARGV.length != 1
|
55
|
+
@input_file = ARGV[0]
|
56
|
+
end
|
57
|
+
|
58
|
+
mcbean = case @input_format
|
59
|
+
when "html"
|
60
|
+
McBean.document(open(@input_file))
|
61
|
+
else
|
62
|
+
McBean.send(@input_format, open(@input_file))
|
63
|
+
end
|
64
|
+
|
65
|
+
puts mcbean.send("to_#{@output_format}")
|
66
|
+
|
67
|
+
exit 0
|
data/lib/mcbean.rb
CHANGED
@@ -1,36 +1,82 @@
|
|
1
1
|
require "loofah"
|
2
2
|
|
3
|
+
#
|
4
|
+
# McBean can convert documents from one format to another.
|
5
|
+
#
|
6
|
+
# See the README.rdoc for more details and examples.
|
7
|
+
#
|
3
8
|
class McBean
|
4
|
-
|
9
|
+
# Current version of McBean
|
10
|
+
VERSION = "0.3.0"
|
11
|
+
|
12
|
+
# Minimum required version of Loofah
|
5
13
|
REQUIRED_LOOFAH_VERSION = "0.4.7"
|
6
14
|
|
7
|
-
|
15
|
+
attr_writer :__html__ # :nodoc:
|
16
|
+
|
17
|
+
private_class_method :new, :allocate
|
8
18
|
|
19
|
+
@@__formats__ = ["html"]
|
20
|
+
|
21
|
+
##
|
22
|
+
# Create a McBean from an HTML fragment string (or IO object)
|
23
|
+
#
|
24
|
+
# Please see README.rdoc for more information on HTML fragments and documents.
|
25
|
+
#
|
9
26
|
def McBean.fragment(string_or_io)
|
10
|
-
mcbean =
|
11
|
-
mcbean.
|
27
|
+
mcbean = new
|
28
|
+
mcbean.__html__ = Loofah.fragment(string_or_io)
|
12
29
|
mcbean
|
13
30
|
end
|
14
31
|
|
32
|
+
##
|
33
|
+
# Create a McBean from an HTML document string (or IO object)
|
34
|
+
#
|
35
|
+
# Please see README.rdoc for more information on HTML fragments and documents.
|
36
|
+
#
|
15
37
|
def McBean.document(string_or_io)
|
16
|
-
mcbean =
|
17
|
-
mcbean.
|
38
|
+
mcbean = new
|
39
|
+
mcbean.__html__ = Loofah.document(string_or_io)
|
18
40
|
mcbean
|
19
41
|
end
|
20
42
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
43
|
+
##
|
44
|
+
# Returns an array of formats that McBean supports.
|
45
|
+
#
|
46
|
+
def McBean.formats
|
47
|
+
@@__formats__
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Generate an HTML string representation of the McBeaned document.
|
52
|
+
#
|
53
|
+
# So you can convert documents in other formats to HTML as follows:
|
54
|
+
#
|
55
|
+
# McBean.markdown(File.read(path_to_markdown_file)).to_html
|
56
|
+
#
|
57
|
+
def to_html
|
58
|
+
__html__.dup.scrub!(:escape).to_html
|
59
|
+
end
|
60
|
+
|
61
|
+
def __html__ # :nodoc:
|
62
|
+
@__html__ ||= nil
|
63
|
+
unless @__html__
|
64
|
+
(McBean.formats - ["html"]).each do |format|
|
65
|
+
obj = send("__#{format}__", false)
|
66
|
+
if obj
|
67
|
+
@__html__ = Loofah.document(obj.to_html)
|
68
|
+
break
|
69
|
+
end
|
70
|
+
end
|
26
71
|
end
|
72
|
+
@__html__
|
27
73
|
end
|
28
74
|
end
|
29
75
|
Mcbean = McBean
|
30
76
|
|
31
77
|
require "mcbean/markdown"
|
78
|
+
require "mcbean/textile"
|
32
79
|
|
33
80
|
if Loofah::VERSION < McBean::REQUIRED_LOOFAH_VERSION
|
34
81
|
raise RuntimeError, "McBean requires Loofah #{McBean::REQUIRED_LOOFAH_VERSION} or later (currently #{Loofah::VERSION})"
|
35
82
|
end
|
36
|
-
|
data/lib/mcbean/markdown.rb
CHANGED
@@ -1,6 +1,42 @@
|
|
1
1
|
require 'rdiscount'
|
2
2
|
|
3
3
|
class McBean
|
4
|
+
attr_writer :__markdown__ # :nodoc:
|
5
|
+
|
6
|
+
@@__formats__ << "markdown"
|
7
|
+
|
8
|
+
##
|
9
|
+
# Create a McBean from a Markdown document string (or IO object)
|
10
|
+
#
|
11
|
+
def McBean.markdown(string_or_io)
|
12
|
+
mcbean = new
|
13
|
+
mcbean.__markdown__ = McBean::Markdownify::Antidote.new(string_or_io.respond_to?(:read) ? string_or_io.read : string_or_io)
|
14
|
+
mcbean
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Generate a Markdown string representation of the McBeaned document.
|
19
|
+
#
|
20
|
+
# So you can convert documents in other formats to Markdown as follows:
|
21
|
+
#
|
22
|
+
# McBean.fragment(File.read(path_to_html_file)).to_markdown
|
23
|
+
#
|
24
|
+
def to_markdown
|
25
|
+
__markdown__.text
|
26
|
+
end
|
27
|
+
|
28
|
+
def __markdown__ generate_from_html_if_necessary=true # :nodoc:
|
29
|
+
@__markdown__ ||= nil
|
30
|
+
if @__markdown__.nil? && generate_from_html_if_necessary
|
31
|
+
@__markdown__ = McBean::Markdownify::Antidote.new(
|
32
|
+
Loofah::Helpers.remove_extraneous_whitespace(
|
33
|
+
__html__.dup.scrub!(:escape).scrub!(Markdownify.new).text(:encode_special_chars => false)
|
34
|
+
))
|
35
|
+
end
|
36
|
+
@__markdown__
|
37
|
+
end
|
38
|
+
|
39
|
+
# :stopdoc:
|
4
40
|
class Markdownify < Loofah::Scrubber
|
5
41
|
Antidote = ::RDiscount # could conceivably be BlueCloth
|
6
42
|
|
@@ -88,10 +124,5 @@ class McBean
|
|
88
124
|
(node.document.serialize_root || node.ancestors.last).children.last
|
89
125
|
end
|
90
126
|
end
|
91
|
-
|
92
|
-
def to_markdown
|
93
|
-
Loofah::Helpers.remove_extraneous_whitespace \
|
94
|
-
html.dup.scrub!(:prune).scrub!(Markdownify.new).text(:encode_special_chars => false)
|
95
|
-
end
|
127
|
+
# :startdoc:
|
96
128
|
end
|
97
|
-
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'redcloth'
|
2
|
+
|
3
|
+
class McBean
|
4
|
+
attr_writer :__textile__ # :nodoc:
|
5
|
+
|
6
|
+
@@__formats__ << "textile"
|
7
|
+
|
8
|
+
##
|
9
|
+
# Create a McBean from a Textile document string (or IO object)
|
10
|
+
#
|
11
|
+
def McBean.textile string_or_io
|
12
|
+
mcbean = new
|
13
|
+
mcbean.__textile__ = McBean::Textilify::Antidote.new(string_or_io.respond_to?(:read) ? string_or_io.read : string_or_io)
|
14
|
+
mcbean
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Generate a Textile string representation of the McBeaned document.
|
19
|
+
#
|
20
|
+
# So you can convert documents in other formats to Textile as follows:
|
21
|
+
#
|
22
|
+
# McBean.fragment(File.read(path_to_html_file)).to_textile
|
23
|
+
#
|
24
|
+
def to_textile
|
25
|
+
__textile__.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def __textile__ generate_from_html_if_necessary=true # :nodoc:
|
29
|
+
@__textile__ ||= nil
|
30
|
+
if @__textile__.nil? && generate_from_html_if_necessary
|
31
|
+
@__textile__ = McBean::Textilify::Antidote.new(
|
32
|
+
Loofah::Helpers.remove_extraneous_whitespace(
|
33
|
+
__html__.dup.scrub!(:escape).scrub!(Textilify.new).text(:encode_special_chars => false)
|
34
|
+
))
|
35
|
+
end
|
36
|
+
@__textile__
|
37
|
+
end
|
38
|
+
|
39
|
+
# :stopdoc:
|
40
|
+
class Textilify < Loofah::Scrubber
|
41
|
+
Antidote = ::RedCloth::TextileDoc
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
@direction = :bottom_up
|
45
|
+
@link_references = nil
|
46
|
+
@link_reference_count = 0
|
47
|
+
end
|
48
|
+
|
49
|
+
def scrub(node)
|
50
|
+
return CONTINUE if node.text?
|
51
|
+
replacement_killer = \
|
52
|
+
case node.name
|
53
|
+
when "h1"
|
54
|
+
new_text node, "\nh1. #{node.content}\n"
|
55
|
+
when "h2"
|
56
|
+
new_text node, "\nh2. #{node.content}\n"
|
57
|
+
when "h3"
|
58
|
+
new_text node, "\nh3. #{node.content}\n"
|
59
|
+
when "h4"
|
60
|
+
new_text node, "\nh4. #{node.content}\n"
|
61
|
+
when "blockquote"
|
62
|
+
new_text node, "\nbq. #{node.content.gsub(/\n\n/, "\n").sub(/^\n/,'')}"
|
63
|
+
when "li"
|
64
|
+
nil # handled by parent list tag
|
65
|
+
when "ul"
|
66
|
+
fragment = []
|
67
|
+
node.xpath("./li").each do |li|
|
68
|
+
fragment << "* #{li.text}" if li.text =~ /\S/
|
69
|
+
end
|
70
|
+
new_text node, "\n#{fragment.join("\n")}\n"
|
71
|
+
when "ol"
|
72
|
+
fragment = []
|
73
|
+
node.xpath("./li").each do |li|
|
74
|
+
fragment << "# #{li.text}" if li.text =~ /\S/
|
75
|
+
end
|
76
|
+
new_text node, "\n#{fragment.join("\n")}\n"
|
77
|
+
when "code"
|
78
|
+
if node.parent.name == "pre"
|
79
|
+
new_text node, node.content.sub(/^/,"bc. ")
|
80
|
+
else
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
when "br"
|
84
|
+
new_text node, "\n"
|
85
|
+
when "a"
|
86
|
+
if node['href'].nil?
|
87
|
+
new_text node, node.content
|
88
|
+
elsif node['title']
|
89
|
+
new_text node, %Q{["#{node.text} (#{node['title']})":#{node['href']}]}
|
90
|
+
else
|
91
|
+
new_text node, %Q{["#{node.text}":#{node['href']}]}
|
92
|
+
end
|
93
|
+
else
|
94
|
+
if Loofah::HashedElements::BLOCK_LEVEL[node.name]
|
95
|
+
new_text node, "\n#{node.content}\n"
|
96
|
+
else
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
node.replace(replacement_killer) if replacement_killer
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def new_text(node, text)
|
106
|
+
Nokogiri::XML::Text.new(text, node.document)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
# :startdoc:
|
110
|
+
end
|
data/test/helper.rb
CHANGED
data/test/test_markdown.rb
CHANGED
@@ -1,132 +1,149 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
describe McBean::Markdownify do
|
4
|
+
describe ".markdown" do
|
5
|
+
describe "passed a string" do
|
6
|
+
it "sets #__markdown__ to be a Markdownify::Antidote" do
|
7
|
+
McBean.markdown("hello\n=====\n").__markdown__.must_be_instance_of McBean::Markdownify::Antidote
|
8
8
|
end
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
describe "passed an IO" do
|
12
|
+
it "sets #__markdown__ to be a Markdownify::Antidote" do
|
13
|
+
io = StringIO.new "hello\n=====\n"
|
14
|
+
McBean.markdown(io).__markdown__.must_be_instance_of McBean::Markdownify::Antidote
|
12
15
|
end
|
16
|
+
end
|
17
|
+
end
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
19
|
+
describe "#to_html" do
|
20
|
+
attr_accessor :mcbean
|
17
21
|
|
18
|
-
|
19
|
-
|
22
|
+
describe "on an instance created by .markdown" do
|
23
|
+
before do
|
24
|
+
@mcbean = McBean.markdown "ohai!\n=====\n"
|
20
25
|
end
|
21
26
|
|
22
|
-
|
23
|
-
|
27
|
+
it "returns an html string" do
|
28
|
+
html = mcbean.to_html
|
29
|
+
html.must_be_instance_of String
|
30
|
+
html.must_match %r{<h1>ohai!</h1>}
|
24
31
|
end
|
32
|
+
end
|
33
|
+
end
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
35
|
+
describe "#to_markdown" do
|
36
|
+
it "add whitespace around block elements" do
|
37
|
+
assert_markdown "before<div>inner</div>after", "before\ninner\nafter", false
|
38
|
+
end
|
30
39
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# <<-EOM
|
35
|
-
# > Hello
|
36
|
-
# >
|
37
|
-
# > > Nested
|
38
|
-
# >
|
39
|
-
# > Goodbye
|
40
|
-
# EOM
|
41
|
-
# )
|
42
|
-
# end
|
43
|
-
|
44
|
-
should "convert unordered list" do
|
45
|
-
assert_markdown "<ul>\n<li>one</li>\n<li>two</li>\n<li>three</li>\n</ul>\n",
|
46
|
-
"\n* one\n* two\n* three\n"
|
47
|
-
end
|
40
|
+
it "convert h1 tag" do
|
41
|
+
assert_markdown "<h1>Foo</h1>", "\nFoo\n==========\n"
|
42
|
+
end
|
48
43
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
44
|
+
it "convert h2 tag" do
|
45
|
+
assert_markdown "<h2>Foo</h2>", "\nFoo\n----------\n"
|
46
|
+
end
|
53
47
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
false
|
58
|
-
end
|
48
|
+
it "convert h3 tag" do
|
49
|
+
assert_markdown "<h3>Foo</h3>", "\n### Foo ###\n"
|
50
|
+
end
|
59
51
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
false
|
64
|
-
end
|
52
|
+
it "convert h4 tag" do
|
53
|
+
assert_markdown "<h4>Foo</h4>", "\n#### Foo ####\n"
|
54
|
+
end
|
65
55
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
56
|
+
it "convert blockquote tag" do
|
57
|
+
assert_markdown "<blockquote><p>Hello\nGoodbye</p></blockquote>",
|
58
|
+
"> Hello\n> Goodbye\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
# it "convert nested blockquote tag" do
|
62
|
+
# assert_markdown(
|
63
|
+
# "<blockquote><p>Hello</p>\n\n<blockquote><p>Nested</p></blockquote>\n\n<p>Goodbye</p></blockquote>",
|
64
|
+
# <<-EOM
|
65
|
+
# > Hello
|
66
|
+
# >
|
67
|
+
# > > Nested
|
68
|
+
# >
|
69
|
+
# > Goodbye
|
70
|
+
# EOM
|
71
|
+
# )
|
72
|
+
# end
|
73
|
+
|
74
|
+
it "convert unordered list" do
|
75
|
+
assert_markdown "<ul>\n<li>one</li>\n<li>two</li>\n<li>three</li>\n</ul>\n",
|
76
|
+
"\n* one\n* two\n* three\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "convert ordered list" do
|
80
|
+
assert_markdown "<ol>\n<li>one</li>\n<li>two</li>\n<li>three</li>\n</ol>\n",
|
81
|
+
"\n1. one\n2. two\n3. three\n"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "ignore empty unordered list items" do
|
85
|
+
assert_markdown "<ul>\n<li>one</li>\n<li></li>\n<li>three</li>\n</ul>\n",
|
86
|
+
"\n* one\n* three\n",
|
87
|
+
false
|
88
|
+
end
|
70
89
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
90
|
+
it "ignore empty ordered list items" do
|
91
|
+
assert_markdown "<ol>\n<li>one</li>\n<li></li>\n<li>three</li>\n</ol>\n",
|
92
|
+
"\n1. one\n3. three\n",
|
93
|
+
false
|
94
|
+
end
|
95
|
+
|
96
|
+
it "convert code blocks" do
|
97
|
+
assert_markdown "<pre><code>This is a code block\ncontinued\n</code></pre>",
|
98
|
+
"\n This is a code block\n continued\n\n"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "convert <br> tags to newlines" do
|
102
|
+
assert_markdown "<div>hello<br>there</div>",
|
103
|
+
"\nhello\nthere\n",
|
104
|
+
false
|
105
|
+
assert_markdown "<div>hello<br />there</div>",
|
106
|
+
"\nhello\nthere\n",
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "anchors" do
|
111
|
+
it "convert <a> tags" do
|
112
|
+
assert_markdown "<p>Yes, magic helmet. And <a href=\"http://sample.com/\">I'll give you a sample</a>.</p>",
|
113
|
+
"\nYes, magic helmet. And [I'll give you a sample](http://sample.com/).\n"
|
78
114
|
end
|
79
115
|
|
80
|
-
|
81
|
-
|
82
|
-
assert_markdown "<
|
83
|
-
"\
|
84
|
-
|
116
|
+
describe "<a> tags without hrefs" do
|
117
|
+
it "be ignored" do
|
118
|
+
assert_markdown "<div><a name='link-target'>target title</a></div>",
|
119
|
+
"\ntarget title\n",
|
120
|
+
false
|
85
121
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
122
|
+
assert_markdown "<div><a id='link-target'>target title</a></div>",
|
123
|
+
"\ntarget title\n",
|
124
|
+
false
|
125
|
+
end
|
126
|
+
end
|
91
127
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
128
|
+
describe "<a> tags with titles" do
|
129
|
+
it "convert fq urls to reference-style" do
|
130
|
+
assert_markdown2 "<p>Yes, magic helmet. And <a href=\"http://sample.com/\" title=\"Fudd\">I'll give you a sample</a>.</p>",
|
131
|
+
"\nYes, magic helmet. And [I'll give you a sample][1].\n\n[1]: http://sample.com/ \"Fudd\"\n"
|
96
132
|
end
|
97
133
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
"\nYes, magic helmet. And [I'll give you a sample][1].\n\n[1]: http://sample.com/ \"Fudd\"\n"
|
102
|
-
end
|
103
|
-
|
104
|
-
should "convert relative urls to reference-style" do
|
105
|
-
assert_markdown2 "<p>Yes, magic helmet. And <a href=\"/home\" title=\"Fudd\">I'll give you a sample</a>.</p>",
|
106
|
-
"\nYes, magic helmet. And [I'll give you a sample][1].\n\n[1]: /home \"Fudd\"\n"
|
107
|
-
end
|
108
|
-
|
109
|
-
should "convert multiple to appear in order at the end of the document" do
|
110
|
-
assert_markdown2 "<p>See <a href=\"/prefs\" title=\"Prefs\">Prefs</a> and <a href=\"/home\" title=\"Home\">Home</a>.</p>",
|
111
|
-
"\nSee [Prefs][1] and [Home][2].\n\n[1]: /prefs \"Prefs\"\n[2]: /home \"Home\"\n"
|
112
|
-
end
|
134
|
+
it "convert relative urls to reference-style" do
|
135
|
+
assert_markdown2 "<p>Yes, magic helmet. And <a href=\"/home\" title=\"Fudd\">I'll give you a sample</a>.</p>",
|
136
|
+
"\nYes, magic helmet. And [I'll give you a sample][1].\n\n[1]: /home \"Fudd\"\n"
|
113
137
|
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
138
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
should "convert markdown into html" do
|
122
|
-
assert_equal "<h1>hello</h1>\n", McBean.markdown("hello\n=====\n").to_html
|
139
|
+
it "convert multiple to appear in order at the end of the document" do
|
140
|
+
assert_markdown2 "<p>See <a href=\"/prefs\" title=\"Prefs\">Prefs</a> and <a href=\"/home\" title=\"Home\">Home</a>.</p>",
|
141
|
+
"\nSee [Prefs][1] and [Home][2].\n\n[1]: /prefs \"Prefs\"\n[2]: /home \"Home\"\n"
|
123
142
|
end
|
124
143
|
end
|
125
144
|
end
|
126
145
|
end
|
127
146
|
|
128
|
-
private
|
129
|
-
|
130
147
|
def assert_markdown html, markdown, roundtrip=true
|
131
148
|
assert_equal(html, McBean::Markdownify::Antidote.new(markdown).to_html.chomp, "markdown roundtrip failed") if roundtrip
|
132
149
|
assert_equal(markdown, McBean.fragment(html).to_markdown, "fragment transformation failed")
|
@@ -142,3 +159,25 @@ class TestMcBeanMarkdown < Test::Unit::TestCase
|
|
142
159
|
McBean.document("<div>#{html}</div>").to_markdown, "document transformation failed")
|
143
160
|
end
|
144
161
|
end
|
162
|
+
|
163
|
+
describe McBean::Markdownify::Antidote do
|
164
|
+
describe "given that RDiscount is already pretty well tested, let's limit ourselves to a token test case" do
|
165
|
+
it "convert markdown into html" do
|
166
|
+
McBean.markdown("hello\n=====\n").to_html.must_match %r{<body><h1>hello</h1></body>}
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "given markdown with an unsafe tag" do
|
171
|
+
it "escapes the tag" do
|
172
|
+
markdown = "hello\n=====\n\n<script>alert('ohai!');</script>\n\nLOL\n"
|
173
|
+
McBean.markdown(markdown).to_html.must_include "<body>\n<h1>hello</h1>\n\n<script>alert('ohai!');</script><p>LOL</p>\n</body>"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "given markdown with an invalid tag" do
|
178
|
+
it "escapes the tag" do
|
179
|
+
markdown = "hello\n=====\n\n<xyzzy>Adventure!</xyzzy>\n\nLOL\n"
|
180
|
+
McBean.markdown(markdown).to_html.must_match %r{<body>\n<h1>hello</h1>\n\n<p><xyzzy>Adventure!</xyzzy></p>\n\n<p>LOL</p>\n</body>}
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
data/test/test_mcbean.rb
CHANGED
@@ -1,52 +1,66 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
describe McBean do
|
4
|
+
describe "class name" do
|
5
|
+
it "sets McBean and Mcbean to be the same thing" do
|
6
6
|
assert McBean == Mcbean
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
assert_match( /OK/, result)
|
14
|
-
assert_no_match( /BAD/, result)
|
10
|
+
describe ".new" do
|
11
|
+
it "cannot be called" do
|
12
|
+
proc { McBean.new }.must_raise NoMethodError
|
15
13
|
end
|
16
14
|
end
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
describe ".allocate" do
|
17
|
+
it "cannot be called" do
|
18
|
+
proc { McBean.allocate }.must_raise NoMethodError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".fragment" do
|
23
|
+
it "sets #__html__ to be a Loofah fragment" do
|
24
|
+
McBean.fragment("<h1>hello</h1>\n").__html__.must_be_instance_of Loofah::HTML::DocumentFragment
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe ".document" do
|
29
|
+
it "sets #__html__ to be a Loofah document" do
|
30
|
+
McBean.document("<h1>hello</h1>\n").__html__.must_be_instance_of Loofah::HTML::Document
|
25
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#to_html" do
|
35
|
+
attr_accessor :mcbean
|
36
|
+
|
37
|
+
it "escapes unsafe tags" do
|
38
|
+
result = McBean.fragment("<div>OK</div><script>BAD</script>").to_html
|
39
|
+
result.must_include "<div>OK</div>"
|
40
|
+
result.must_include "<script>BAD</script>"
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "on an instance created by .fragment" do
|
44
|
+
before do
|
45
|
+
@mcbean = McBean.fragment "<div>ohai!</div>"
|
46
|
+
end
|
26
47
|
|
27
|
-
|
28
|
-
|
29
|
-
html
|
30
|
-
|
31
|
-
McBean.document html
|
48
|
+
it "returns an html string" do
|
49
|
+
html = mcbean.to_html
|
50
|
+
html.must_be_instance_of String
|
51
|
+
html.must_match %r{<div>ohai!</div>}
|
32
52
|
end
|
33
53
|
end
|
34
54
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
mock.proxy(McBean::Markdownify::Antidote).new(anything).once
|
39
|
-
assert_equal "<h1>hello</h1>\n", McBean.markdown("hello\n=====\n").to_html
|
40
|
-
end
|
55
|
+
describe "on an instance created by .fragment" do
|
56
|
+
before do
|
57
|
+
@mcbean = McBean.document "<div>ohai!</div>"
|
41
58
|
end
|
42
59
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
mock.proxy(io).read.once
|
48
|
-
assert_equal "<h1>hello</h1>\n", McBean.markdown(io).to_html
|
49
|
-
end
|
60
|
+
it "returns an html string" do
|
61
|
+
html = mcbean.to_html
|
62
|
+
html.must_be_instance_of String
|
63
|
+
html.must_match %r{<div>ohai!</div>}
|
50
64
|
end
|
51
65
|
end
|
52
66
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.dirname(__FILE__) + "/helper"
|
3
|
+
|
4
|
+
describe McBean::Textilify do
|
5
|
+
describe ".textile" do
|
6
|
+
describe "passed a string" do
|
7
|
+
it "sets #__textile__ to be a Textilify::Antidote" do
|
8
|
+
McBean.textile("h1. hello").__textile__.must_be_instance_of McBean::Textilify::Antidote
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "passed an IO" do
|
13
|
+
it "sets #__textile__ to be a Textilify::Antidote" do
|
14
|
+
io = StringIO.new "h1. hello"
|
15
|
+
McBean.textile(io).__textile__.must_be_instance_of McBean::Textilify::Antidote
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#to_html" do
|
21
|
+
attr_accessor :mcbean
|
22
|
+
|
23
|
+
describe "on an instance created by .textile" do
|
24
|
+
before do
|
25
|
+
@mcbean = McBean.textile "h1. ohai!"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns an html string" do
|
29
|
+
html = mcbean.to_html
|
30
|
+
html.must_be_instance_of String
|
31
|
+
html.must_match %r{<h1>ohai!</h1>}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#to_textile" do
|
37
|
+
it "adds whitespace around block elements" do
|
38
|
+
assert_textile "before<div>inner</div>after", "before\ninner\nafter", false
|
39
|
+
end
|
40
|
+
|
41
|
+
it "converts h1 tag" do
|
42
|
+
assert_textile "<h1>Foo</h1>", "\nh1. Foo\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "converts h2 tag" do
|
46
|
+
assert_textile "<h2>Foo</h2>", "\nh2. Foo\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "converts h3 tag" do
|
50
|
+
assert_textile "<h3>Foo</h3>", "\nh3. Foo\n"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "converts h4 tag" do
|
54
|
+
assert_textile "<h4>Foo</h4>", "\nh4. Foo\n"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "converts blockquote tag" do
|
58
|
+
assert_textile "<blockquote>\n<p>foo fazz<br />\nbizz buzz<br />\nwang wong</p>\n</blockquote>", "\nbq. foo fazz\nbizz buzz\nwang wong\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "converts ul lists" do
|
62
|
+
html = "<ul>\n\t<li>foo</li>\n\t<li>wuxx</li>\n</ul>"
|
63
|
+
textile = "\n* foo\n* wuxx\n"
|
64
|
+
assert_textile html, textile
|
65
|
+
end
|
66
|
+
|
67
|
+
it "converts ol lists" do
|
68
|
+
html = "<ol>\n\t<li>foo</li>\n\t<li>wuxx</li>\n</ol>"
|
69
|
+
textile = "\n# foo\n# wuxx\n"
|
70
|
+
assert_textile html, textile
|
71
|
+
end
|
72
|
+
|
73
|
+
it "ignores empty unordered list items" do
|
74
|
+
assert_textile "<ul>\n<li>one</li>\n<li></li>\n<li>three</li>\n</ul>\n",
|
75
|
+
"\n* one\n* three\n",
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
it "ignores empty ordered list items" do
|
80
|
+
assert_textile "<ol>\n<li>one</li>\n<li></li>\n<li>three</li>\n</ol>\n",
|
81
|
+
"\n# one\n# three\n",
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
it "converts code blocks" do
|
86
|
+
assert_textile "<pre><code>This is a code block\ncontinued</code></pre>",
|
87
|
+
"\nbc. This is a code block\ncontinued\n"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "converts <br> tags to newlines" do
|
91
|
+
assert_textile "<p>hello<br>there</p>", "\nhello\nthere\n", false
|
92
|
+
assert_textile "<p>hello<br />there</p>", "\nhello\nthere\n", false
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "anchors" do
|
96
|
+
it "converts <a> tags" do
|
97
|
+
assert_textile "<p>Yes, magic helmet. And <a href=\"http://sample.com/\">I will give you a sample</a>.</p>",
|
98
|
+
%Q{\nYes, magic helmet. And ["I will give you a sample":http://sample.com/].\n}
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "<a> tags without hrefs" do
|
102
|
+
it "ignores them" do
|
103
|
+
assert_textile "<div><a name='link-target'>target title</a></div>",
|
104
|
+
"\ntarget title\n",
|
105
|
+
false
|
106
|
+
|
107
|
+
assert_textile "<div><a id='link-target'>target title</a></div>",
|
108
|
+
"\ntarget title\n",
|
109
|
+
false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "<a> tags with titles" do
|
114
|
+
it "include the title" do
|
115
|
+
assert_textile %Q{<p>Yes, magic helmet. And <a href="http://sample.com/" title="Fudd">I will give you a sample</a>.</p>},
|
116
|
+
%Q{\nYes, magic helmet. And ["I will give you a sample (Fudd)":http://sample.com/].\n}, false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def assert_textile html, textile, roundtrip=true
|
123
|
+
assert_equal(html, McBean::Textilify::Antidote.new(textile).to_html, "textile roundtrip failed") if roundtrip
|
124
|
+
assert_equal(textile, McBean.fragment(html).to_textile, "fragment transformation failed")
|
125
|
+
assert_equal(Loofah::Helpers.remove_extraneous_whitespace("\n#{textile}\n"),
|
126
|
+
McBean.document("<div>#{html}</div>").to_textile, "document transformation failed")
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
describe McBean::Textilify::Antidote do
|
132
|
+
describe "given that RedCloth is already pretty well tested, let's limit ourselves to a token test case" do
|
133
|
+
it "convert textile into html" do
|
134
|
+
McBean.textile("h1. hello").to_html.must_match %r{<body><h1>hello</h1></body>}
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "given textile with an unsafe tag" do
|
139
|
+
it "escapes the tag" do
|
140
|
+
textile = "h1. hello\n\n<script>alert('ohai!');</script>\n\nlol\n"
|
141
|
+
McBean.textile(textile).to_html.must_include "<body>\n<h1>hello</h1>\n<script>alert('ohai!');</script><p>lol</p>\n</body>"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "given textile with an invalid tag" do
|
146
|
+
it "escapes the tag" do
|
147
|
+
textile = "h1. hello\n\n<xyzzy>Adventure!</xyzzy>\n\nlol\n"
|
148
|
+
McBean.textile(textile).to_html.must_match %r{<body>\n<h1>hello</h1>\n<xyzzy>Adventure!</xyzzy><p>lol</p>\n</body>}
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mike Dalessio
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
FlqnTjy13J3nD30uxy9a1g==
|
36
36
|
-----END CERTIFICATE-----
|
37
37
|
|
38
|
-
date: 2010-
|
38
|
+
date: 2010-04-18 00:00:00 -04:00
|
39
39
|
default_executable:
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -67,84 +67,71 @@ dependencies:
|
|
67
67
|
type: :runtime
|
68
68
|
version_requirements: *id002
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: RedCloth
|
71
71
|
prerelease: false
|
72
72
|
requirement: &id003 !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
74
|
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
segments:
|
77
|
-
-
|
77
|
+
- 4
|
78
78
|
- 0
|
79
|
-
-
|
80
|
-
version:
|
81
|
-
type: :
|
79
|
+
- 0
|
80
|
+
version: 4.0.0
|
81
|
+
type: :runtime
|
82
82
|
version_requirements: *id003
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rubyforge
|
85
85
|
prerelease: false
|
86
86
|
requirement: &id004 !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
88
|
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
segments:
|
91
|
+
- 2
|
91
92
|
- 0
|
92
93
|
- 3
|
93
|
-
|
94
|
-
version: 0.3.0
|
94
|
+
version: 2.0.3
|
95
95
|
type: :development
|
96
96
|
version_requirements: *id004
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: minitest
|
99
99
|
prerelease: false
|
100
100
|
requirement: &id005 !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
102
|
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
segments:
|
105
|
-
-
|
106
|
-
-
|
107
|
-
version: "2.10"
|
108
|
-
type: :development
|
109
|
-
version_requirements: *id005
|
110
|
-
- !ruby/object:Gem::Dependency
|
111
|
-
name: rr
|
112
|
-
prerelease: false
|
113
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
segments:
|
105
|
+
- 1
|
106
|
+
- 6
|
118
107
|
- 0
|
119
|
-
|
120
|
-
- 4
|
121
|
-
version: 0.10.4
|
108
|
+
version: 1.6.0
|
122
109
|
type: :development
|
123
|
-
version_requirements: *
|
110
|
+
version_requirements: *id005
|
124
111
|
- !ruby/object:Gem::Dependency
|
125
112
|
name: hoe
|
126
113
|
prerelease: false
|
127
|
-
requirement: &
|
114
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
128
115
|
requirements:
|
129
116
|
- - ">="
|
130
117
|
- !ruby/object:Gem::Version
|
131
118
|
segments:
|
132
119
|
- 2
|
133
|
-
-
|
120
|
+
- 6
|
134
121
|
- 0
|
135
|
-
version: 2.
|
122
|
+
version: 2.6.0
|
136
123
|
type: :development
|
137
|
-
version_requirements: *
|
124
|
+
version_requirements: *id006
|
138
125
|
description: |-
|
139
|
-
McBean
|
140
|
-
|
126
|
+
McBean can convert documents from one format to another. McBean currently supports:
|
127
|
+
|
128
|
+
* HTML
|
129
|
+
* Markdown (a subset)
|
130
|
+
* Textile (a subset)
|
141
131
|
|
142
|
-
|
143
|
-
Markdown to Textile, and anything in between. It will be the Sylvester
|
144
|
-
McMonkey McBean of markup, placing stars onto the bellies of all kinds
|
145
|
-
of Sneetchy document formats.
|
132
|
+
with the help of Loofah, Nokogiri, RDiscount and RedCloth.
|
146
133
|
|
147
|
-
"You can't teach a Sneetch."
|
134
|
+
"You can't teach a Sneetch." -- Sylvester McMonkey McBean
|
148
135
|
email:
|
149
136
|
- mike.dalessio@gmail.com
|
150
137
|
executables:
|
@@ -152,23 +139,23 @@ executables:
|
|
152
139
|
extensions: []
|
153
140
|
|
154
141
|
extra_rdoc_files:
|
155
|
-
- History.txt
|
156
142
|
- Manifest.txt
|
157
143
|
- CHANGELOG.rdoc
|
158
144
|
- README.rdoc
|
159
145
|
files:
|
160
146
|
- .autotest
|
161
147
|
- CHANGELOG.rdoc
|
162
|
-
- History.txt
|
163
148
|
- Manifest.txt
|
164
149
|
- README.rdoc
|
165
150
|
- Rakefile
|
166
151
|
- bin/mcbean
|
167
152
|
- lib/mcbean.rb
|
168
153
|
- lib/mcbean/markdown.rb
|
154
|
+
- lib/mcbean/textile.rb
|
169
155
|
- test/helper.rb
|
170
156
|
- test/test_markdown.rb
|
171
157
|
- test/test_mcbean.rb
|
158
|
+
- test/test_textile.rb
|
172
159
|
has_rdoc: true
|
173
160
|
homepage: http://github.com/flavorjones/mcbean
|
174
161
|
licenses: []
|
@@ -199,7 +186,8 @@ rubyforge_project: mcbean
|
|
199
186
|
rubygems_version: 1.3.6
|
200
187
|
signing_key:
|
201
188
|
specification_version: 3
|
202
|
-
summary: McBean
|
189
|
+
summary: McBean can convert documents from one format to another
|
203
190
|
test_files:
|
204
191
|
- test/test_mcbean.rb
|
205
192
|
- test/test_markdown.rb
|
193
|
+
- test/test_textile.rb
|
metadata.gz.sig
CHANGED
Binary file
|