mcbean 0.2.0 → 0.3.0

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.tar.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- "5��RiOs+�?�'�/�Z�~�5'%���ٗ]��ce62����P�~��פ�Dґ<Xᚯ}c��-���·�An&HTX}������ޝ�k/ж�!uD}�Sm�p� ?������ �P���>��Pi��{k����7�d���N=���6�])�Z�"Q�qH�&�֤q� ��A��7v''��]�\Qu�M��>
2
- �љ���]ֺ�y,a�Ѿ) G,=�aJ\��Z����ki��@�+
1
+ WBB�����90���\֫5�#�$Kߵ�2f�Fko��%�s��c���
2
+ n���%�I0?-���aI�j@�hk jo ��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���%
@@ -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 into Markdown.
34
+ * Converts HTML documents to Markdown.
@@ -1,12 +1,13 @@
1
1
  .autotest
2
2
  CHANGELOG.rdoc
3
- History.txt
4
3
  Manifest.txt
5
4
  README.rdoc
6
5
  Rakefile
7
6
  bin/mcbean
8
7
  lib/mcbean.rb
9
8
  lib/mcbean/markdown.rb
9
+ lib/mcbean/textile.rb
10
10
  test/helper.rb
11
11
  test/test_markdown.rb
12
12
  test/test_mcbean.rb
13
+ test/test_textile.rb
@@ -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 converts HTML into Markdown, and Markdown into HTML (with the
9
- help of Loofah, Nokogiri and RDiscount).
8
+ McBean can convert documents from one format to another. McBean currently supports:
10
9
 
11
- Its goal is to eventually be able to transform documents from HTML to
12
- Markdown to Textile, and anything in between. It will be the Sylvester
13
- McMonkey McBean of markup, placing stars onto the bellies of all kinds
14
- of Sneetchy document formats.
10
+ * HTML
11
+ * Markdown (a subset)
12
+ * Textile (a subset)
15
13
 
16
- "You can't teach a Sneetch."
14
+ with the help of Loofah, Nokogiri, RDiscount and RedCloth.
17
15
 
18
- == Features / Problems
16
+ "You can't teach a Sneetch." -- Sylvester McMonkey McBean
19
17
 
20
- * Transforms HTML into Markdown, and Markdown into HTML.
21
- * Doesn't do anything else yet.
18
+ == Features
22
19
 
23
- == Synopsis
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
- If you have an HTML fragment, you can convert it into Markdown:
26
+ == Problems
26
27
 
27
- McBean.fragment(your_html).to_markdown
28
+ * Only supports a limited subset of Markdown and Textile. Patches welcome.
28
29
 
29
- Or if you have an HTML document, you can convert it into Markdown:
30
+ == Synopsis
30
31
 
31
- McBean.document(your_html).to_markdown
32
+ Wrap your document (which can be either a String or an IO object):
32
33
 
33
- You can also convert Markdown into HTML (via RDiscount):
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
- McBean.markdown(your_markdown).to_html
39
+ And then generate the desired markup format:
36
40
 
37
- Note that the parameter passed to +fragment+, +document+ and
38
- +markdown+ can be either a String or an IO.
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 /usr/lib/openoffice/licenses/LICENSE_en-GB.html
43
- $ mcbean http://daringfireball.net/projects/markdown/syntax
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
- extra_dev_deps << ["shoulda", ">= 2.10"]
19
- extra_dev_deps << ["rr", ">= 0.10.4"]
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
- unless ARGV[0]
8
- puts "USAGE: #{File.basename(__FILE__)} <file-or-url>"
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 "McBean transforms HTML into Markdown for your reading pleasure."
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
- puts McBean.document(open(ARGV[0])).to_markdown
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
@@ -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
- VERSION = "0.2.0"
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
- attr_accessor :html
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 = allocate
11
- mcbean.html = Loofah.fragment(string_or_io)
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 = allocate
17
- mcbean.html = Loofah.document(string_or_io)
38
+ mcbean = new
39
+ mcbean.__html__ = Loofah.document(string_or_io)
18
40
  mcbean
19
41
  end
20
42
 
21
- def McBean.markdown(string_or_io)
22
- if string_or_io.respond_to?(:read)
23
- McBean::Markdownify::Antidote.new(string_or_io.read)
24
- else
25
- McBean::Markdownify::Antidote.new(string_or_io)
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
-
@@ -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
@@ -1,8 +1,2 @@
1
- require "test/unit"
1
+ require "minitest/autorun"
2
2
  require "mcbean"
3
- require "shoulda"
4
- require "rr"
5
-
6
- class Test::Unit::TestCase
7
- include RR::Adapters::TestUnit
8
- end
@@ -1,132 +1,149 @@
1
1
  require File.dirname(__FILE__) + "/helper"
2
2
 
3
- class TestMcBeanMarkdown < Test::Unit::TestCase
4
- context McBean::Markdownify do
5
- context "#to_markdown" do
6
- should "add whitespace around block elements" do
7
- assert_markdown "before<div>inner</div>after", "before\ninner\nafter", false
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
- should "convert h1 tag" do
11
- assert_markdown "<h1>Foo</h1>", "\nFoo\n==========\n"
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
- should "convert h2 tag" do
15
- assert_markdown "<h2>Foo</h2>", "\nFoo\n----------\n"
16
- end
19
+ describe "#to_html" do
20
+ attr_accessor :mcbean
17
21
 
18
- should "convert h3 tag" do
19
- assert_markdown "<h3>Foo</h3>", "\n### Foo ###\n"
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
- should "convert h4 tag" do
23
- assert_markdown "<h4>Foo</h4>", "\n#### Foo ####\n"
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
- should "convert blockquote tag" do
27
- assert_markdown "<blockquote><p>Hello\nGoodbye</p></blockquote>",
28
- "> Hello\n> Goodbye\n"
29
- end
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
- # should "convert nested blockquote tag" do
32
- # assert_markdown(
33
- # "<blockquote><p>Hello</p>\n\n<blockquote><p>Nested</p></blockquote>\n\n<p>Goodbye</p></blockquote>",
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
- should "convert ordered list" do
50
- assert_markdown "<ol>\n<li>one</li>\n<li>two</li>\n<li>three</li>\n</ol>\n",
51
- "\n1. one\n2. two\n3. three\n"
52
- end
44
+ it "convert h2 tag" do
45
+ assert_markdown "<h2>Foo</h2>", "\nFoo\n----------\n"
46
+ end
53
47
 
54
- should "ignore empty unordered list items" do
55
- assert_markdown "<ul>\n<li>one</li>\n<li></li>\n<li>three</li>\n</ul>\n",
56
- "\n* one\n* three\n",
57
- false
58
- end
48
+ it "convert h3 tag" do
49
+ assert_markdown "<h3>Foo</h3>", "\n### Foo ###\n"
50
+ end
59
51
 
60
- should "ignore empty ordered list items" do
61
- assert_markdown "<ol>\n<li>one</li>\n<li></li>\n<li>three</li>\n</ol>\n",
62
- "\n1. one\n3. three\n",
63
- false
64
- end
52
+ it "convert h4 tag" do
53
+ assert_markdown "<h4>Foo</h4>", "\n#### Foo ####\n"
54
+ end
65
55
 
66
- should "convert code blocks" do
67
- assert_markdown "<pre><code>This is a code block\ncontinued\n</code></pre>",
68
- "\n This is a code block\n continued\n\n"
69
- end
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
- should "convert <br> tags to newlines" do
72
- assert_markdown "<div>hello<br>there</div>",
73
- "\nhello\nthere\n",
74
- false
75
- assert_markdown "<div>hello<br />there</div>",
76
- "\nhello\nthere\n",
77
- false
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
- context "anchors" do
81
- should "convert <a> tags" do
82
- assert_markdown "<p>Yes, magic helmet. And <a href=\"http://sample.com/\">I'll give you a sample</a>.</p>",
83
- "\nYes, magic helmet. And [I'll give you a sample](http://sample.com/).\n"
84
- end
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
- context "<a> tags without hrefs" do
87
- should "be ignored" do
88
- assert_markdown "<div><a name='link-target'>target title</a></div>",
89
- "\ntarget title\n",
90
- false
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
- assert_markdown "<div><a id='link-target'>target title</a></div>",
93
- "\ntarget title\n",
94
- false
95
- end
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
- context "<a> tags with titles" do
99
- should "convert fq urls to reference-style" do
100
- assert_markdown2 "<p>Yes, magic helmet. And <a href=\"http://sample.com/\" title=\"Fudd\">I'll give you a sample</a>.</p>",
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
- context McBean::Markdownify::Antidote do
119
- context "given that RDiscount is already pretty well tested" do
120
- context "let's limit ourselves to a token test case" do
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&lt;script&gt;alert('ohai!');&lt;/script&gt;<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>&lt;xyzzy&gt;Adventure!&lt;/xyzzy&gt;</p>\n\n<p>LOL</p>\n</body>}
181
+ end
182
+ end
183
+ end
@@ -1,52 +1,66 @@
1
1
  require File.dirname(__FILE__) + "/helper"
2
2
 
3
- class TestMcBean < Test::Unit::TestCase
4
- context "class name" do
5
- should "set McBean and Mcbean to be the same thing" do
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
- context "cleanup" do
11
- should "prune unsafe tags" do
12
- result = McBean.fragment("<div>OK</div><script>BAD</script>").to_markdown
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
- context "parsing" do
19
- context "McBean.fragment" do
20
- should "call Loofah.fragment" do
21
- html = "<h1>hello</h1>\n"
22
- mock.proxy(Loofah).fragment(html).once
23
- McBean.fragment html
24
- end
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 "&lt;script&gt;BAD&lt;/script&gt;"
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
- context "McBean.document" do
28
- should "call Loofah.document" do
29
- html = "<h1>hello</h1>\n"
30
- mock.proxy(Loofah).document(html).once
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
- context "McBean.markdown" do
36
- context "passed a string" do
37
- should "create a Markdownify::Antidote" do
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
- context "passed an IO" do
44
- should "create a Markdownify::Antidote" do
45
- io = StringIO.new "hello\n=====\n"
46
- mock.proxy(McBean::Markdownify::Antidote).new(anything).once
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&lt;script&gt;alert('ohai!');&lt;/script&gt;<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&lt;xyzzy&gt;Adventure!&lt;/xyzzy&gt;<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
- - 2
7
+ - 3
8
8
  - 0
9
- version: 0.2.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-03-24 00:00:00 -04:00
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: rubyforge
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
- - 2
77
+ - 4
78
78
  - 0
79
- - 3
80
- version: 2.0.3
81
- type: :development
79
+ - 0
80
+ version: 4.0.0
81
+ type: :runtime
82
82
  version_requirements: *id003
83
83
  - !ruby/object:Gem::Dependency
84
- name: gemcutter
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
- - 0
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: shoulda
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
- - 2
106
- - 10
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
- - 10
120
- - 4
121
- version: 0.10.4
108
+ version: 1.6.0
122
109
  type: :development
123
- version_requirements: *id006
110
+ version_requirements: *id005
124
111
  - !ruby/object:Gem::Dependency
125
112
  name: hoe
126
113
  prerelease: false
127
- requirement: &id007 !ruby/object:Gem::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
- - 5
120
+ - 6
134
121
  - 0
135
- version: 2.5.0
122
+ version: 2.6.0
136
123
  type: :development
137
- version_requirements: *id007
124
+ version_requirements: *id006
138
125
  description: |-
139
- McBean converts HTML into Markdown, and Markdown into HTML (with the
140
- help of Loofah, Nokogiri and RDiscount).
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
- Its goal is to eventually be able to transform documents from HTML to
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 converts HTML into Markdown, and Markdown into HTML (with the help of Loofah, Nokogiri and RDiscount)
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
@@ -1,6 +0,0 @@
1
- === 1.0.0 / 2010-03-08
2
-
3
- * 1 major enhancement
4
-
5
- * Birthday!
6
-