cpjolicoeur-ClothBlue 0.2.2
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/README +3 -0
- data/TODO +1 -0
- data/clothblue.gemspec +14 -0
- data/lib/README.rdoc +46 -0
- data/lib/clothblue.rb +124 -0
- data/test/README +0 -0
- data/test/test_entities.rb +31 -0
- data/test/test_formatting.rb +33 -0
- data/test/test_headings.rb +46 -0
- data/test/test_lists.rb +29 -0
- data/test/test_structure.rb +32 -0
- data/test/test_tables.rb +30 -0
- metadata +70 -0
data/README
ADDED
data/TODO
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* make lists work better. right now they all output as unordered lists. make both <ul> and <ol> list items work correctly.
|
data/clothblue.gemspec
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = "ClothBlue"
|
|
3
|
+
s.version = "0.2.2"
|
|
4
|
+
s.date = "Time.now"
|
|
5
|
+
s.summary = "HTML to Markdown converter"
|
|
6
|
+
s.email = "cpjolicoeur@gmail.com"
|
|
7
|
+
s.homepage = "http://github.com/cpjolicoeur/clothblue"
|
|
8
|
+
s.description = "ClothBlue is BlueCloth's evil twin. It converts existing HTML into Markdown format for use with BlueCloth."
|
|
9
|
+
s.has_rdoc = true
|
|
10
|
+
s.authors = ["Craig P Jolicoeur"]
|
|
11
|
+
s.files = ["README", "TODO", "clothblue.gemspec", "lib/clothblue.rb", "lib/README.rdoc", "test/README", "test/test_entities.rb", "test/test_formatting.rb", "test/test_headings.rb", "test/test_lists.rb", "test/test_structure.rb", "test/test_tables.rb"]
|
|
12
|
+
s.test_files = ["test/test_entities.rb", "test/test_formatting.rb", "test/test_headings.rb", "test/test_lists.rb", "test/test_structure.rb", "test/test_tables.rb"]
|
|
13
|
+
s.rdoc_options = ["--main", "lib/README.rdoc"]
|
|
14
|
+
end
|
data/lib/README.rdoc
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
= ClothBlue HTML 2 Markdown converter
|
|
2
|
+
|
|
3
|
+
== What it is
|
|
4
|
+
|
|
5
|
+
A script to convert HTML into Markdown markup for use, for example, with BlueCloth.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
== Requirements
|
|
9
|
+
|
|
10
|
+
All you need is Ruby.
|
|
11
|
+
|
|
12
|
+
== Get it
|
|
13
|
+
|
|
14
|
+
Available as a gem on GitHub:
|
|
15
|
+
|
|
16
|
+
Or download from:
|
|
17
|
+
|
|
18
|
+
Or get the source:
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
== Features
|
|
22
|
+
|
|
23
|
+
This is alpha software, and only a few Markdown rules have been implemented yet:
|
|
24
|
+
* font markup and weight (<b>, <strong>, ...)
|
|
25
|
+
* text formatting (<sub>, <sup>, <ins>,<del>)
|
|
26
|
+
|
|
27
|
+
== Usage
|
|
28
|
+
|
|
29
|
+
require 'clothblue'
|
|
30
|
+
|
|
31
|
+
text = ClothBlue.new("<b>Bold</b> <em>HTML</em>!")
|
|
32
|
+
text.to_markdown
|
|
33
|
+
|
|
34
|
+
== Get Help
|
|
35
|
+
|
|
36
|
+
Feel free to contact me, or peruse the homepage.
|
|
37
|
+
|
|
38
|
+
* http://craigjolicoeur.com/clothblue/
|
|
39
|
+
* http://github.com/cpjolicoeur/clothblue/
|
|
40
|
+
|
|
41
|
+
== Acknowledgments
|
|
42
|
+
|
|
43
|
+
ClothBlue is heavily copied from the ClothRed library (http://clothred.rubyforge.org/). Much thanks to
|
|
44
|
+
Phillip Gawlowski for the initial idea and code. I basically just ported this HTML to Textile converter
|
|
45
|
+
to work with Markdown instead of Textile. The format of the code and README docs are pretty much exact
|
|
46
|
+
clones as far as the format is concerned.
|
data/lib/clothblue.rb
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
=begin rdoc
|
|
2
|
+
Provides the methods to convert HTML into Markdown.
|
|
3
|
+
*Please* *note*: ClothBlue creates UTF-8 output. To do so, it sets $KCODE to UTF-8. This will be globally available!
|
|
4
|
+
#--
|
|
5
|
+
TODO: enhance docs, as more methods come availlable
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
Author:: Craig P Jolicoeur (mailto:cpjolicoeur@gmail.com)
|
|
9
|
+
Copyright:: Copyright (c) 2008 Phillip Gawlowski
|
|
10
|
+
License:: MIT
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
require 'cgi'
|
|
14
|
+
$KCODE = "U"
|
|
15
|
+
|
|
16
|
+
class ClothBlue < String
|
|
17
|
+
#--
|
|
18
|
+
TEXT_FORMATTING = [
|
|
19
|
+
["<b>", "**"], ["</b>","**"], ["<em>","_"], ["</em>", "_"], ["<b>", "**"],
|
|
20
|
+
["</b>", "**"], ["<code>", "`"], ["<i>","_"], ["</i>", "_"],
|
|
21
|
+
["</code>", "`"], ["<strong>", "**"], ["</strong>", "**"]
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
HEADINGS = [
|
|
25
|
+
["<h1>","# "], ["</h1>", " #\n\n"], ["<h2>","## "], ["</h2>", " ##\n\n"],
|
|
26
|
+
["<h3>","### "], ["</h3>", " ###\n\n"], ["<h4>","#### "], ["</h4>", " ####\n\n"],
|
|
27
|
+
["<h5>","##### "], ["</h5>", " #####\n\n"], ["<h6>","###### "], ["</h6>", " ######\n\n"]
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
STRUCTURES = [
|
|
31
|
+
["<p>", "\n\n"],["</p>","\n\n"], ["<blockquote>", "> "], ["</blockquote>","\n"],
|
|
32
|
+
["<br />", "\n"], ["<br>", "\n"]
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
ENTITIES = [
|
|
36
|
+
["“", '"'], ["”", '"'], ["—", "--"], ["—", "--"],
|
|
37
|
+
["–","-"], ["…", "..."], ["×", " x "], ["™","(TM)"],
|
|
38
|
+
["®","(R)"], ["©","(C)"], ["’", "'"]
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
LISTS = [
|
|
42
|
+
["<ol>", ""], ["</ol>", "\n\n"], ["<ul>", ""], ["</ul>", "\n\n"], ["<li>", "+ "], ["</li>", "\n"]
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
TABLES = [
|
|
46
|
+
["<table>","\n\n<table>"], ["</table>","</table>\n\n"]
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
def initialize (html)
|
|
50
|
+
super(html)
|
|
51
|
+
@workingcopy = html
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#++
|
|
55
|
+
#Call all necessary methods to convert a string of HTML into Markdown markup.
|
|
56
|
+
|
|
57
|
+
def to_markdown
|
|
58
|
+
headings(@workingcopy)
|
|
59
|
+
structure(@workingcopy)
|
|
60
|
+
text_formatting(@workingcopy)
|
|
61
|
+
lists(@workingcopy)
|
|
62
|
+
entities(@workingcopy)
|
|
63
|
+
tables(@workingcopy)
|
|
64
|
+
@workingcopy = CGI::unescapeHTML(@workingcopy)
|
|
65
|
+
@workingcopy
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#--
|
|
69
|
+
#The conversion methods themselves are private.
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def text_formatting(text)
|
|
73
|
+
TEXT_FORMATTING.each do |htmltag, markdowntag|
|
|
74
|
+
text.gsub!(htmltag, markdowntag)
|
|
75
|
+
end
|
|
76
|
+
text
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def headings(text)
|
|
81
|
+
HEADINGS.each do |htmltag, markdowntag|
|
|
82
|
+
text.gsub!(htmltag, markdowntag)
|
|
83
|
+
end
|
|
84
|
+
text
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def lists(text)
|
|
89
|
+
LISTS.each do |htmltag, markdowntag|
|
|
90
|
+
text.gsub!(htmltag, markdowntag)
|
|
91
|
+
end
|
|
92
|
+
text
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def entities(text)
|
|
97
|
+
ENTITIES.each do |htmlentity, markdownentity|
|
|
98
|
+
text.gsub!(htmlentity, markdownentity)
|
|
99
|
+
end
|
|
100
|
+
text
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def structure(text)
|
|
105
|
+
STRUCTURES.each do |htmltag, markdowntag|
|
|
106
|
+
text.gsub!(htmltag, markdowntag)
|
|
107
|
+
end
|
|
108
|
+
text
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def tables(text)
|
|
112
|
+
TABLES.each do |htmltag, markdowntag|
|
|
113
|
+
text.gsub!(htmltag, markdowntag)
|
|
114
|
+
end
|
|
115
|
+
text
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def css_styles(text)
|
|
120
|
+
#TODO: Translate CSS-styles
|
|
121
|
+
text
|
|
122
|
+
end
|
|
123
|
+
#++
|
|
124
|
+
end # end class ClothBlue
|
data/test/README
ADDED
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# test_entities.rb
|
|
2
|
+
# May 14, 2008
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
require "rubygems"
|
|
9
|
+
require "clothblue"
|
|
10
|
+
rescue LoadError
|
|
11
|
+
require "clothblue"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require 'test/unit'
|
|
15
|
+
|
|
16
|
+
class TestClothBlueEntities < Test::Unit::TestCase
|
|
17
|
+
|
|
18
|
+
ENTITIES_TEST = [
|
|
19
|
+
["“", '"'], ["”", '"'], ["—", "--"], ["—", "--"],
|
|
20
|
+
["–","-"], ["…", "..."], ["×", " x "], ["™","(TM)"],
|
|
21
|
+
["®","(R)"], ["©","(C)"], ["’", "'"]
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
def test_entities
|
|
25
|
+
ENTITIES_TEST.each do |html, markdown|
|
|
26
|
+
test_html = ClothBlue.new(html)
|
|
27
|
+
result = test_html.to_markdown
|
|
28
|
+
assert_equal(markdown,result)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# test_formatting.rb
|
|
2
|
+
# May 15, 2008
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
#circumventing a require Problem:
|
|
6
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
|
7
|
+
|
|
8
|
+
begin
|
|
9
|
+
require "rubygems"
|
|
10
|
+
require "clothblue"
|
|
11
|
+
rescue LoadError
|
|
12
|
+
require "clothblue"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
require "test/unit"
|
|
16
|
+
|
|
17
|
+
class TestClothBlueFormatting < Test::Unit::TestCase
|
|
18
|
+
|
|
19
|
+
FORMATTING_STRINGS = [
|
|
20
|
+
["<b>bold</b>","**bold**"], ["<strong>strong</strong>", "**strong**"],
|
|
21
|
+
["<em>emphasized</em>", "_emphasized_"],["<i>italics</i>", "_italics_"],
|
|
22
|
+
["<code>ClothBlue#to_markdown</code>", "`ClothBlue#to_markdown`"]
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
def test_textformatting
|
|
26
|
+
FORMATTING_STRINGS.each do |html, markdown|
|
|
27
|
+
test_html = ClothBlue.new(html)
|
|
28
|
+
result = test_html.to_markdown
|
|
29
|
+
assert_equal(markdown,result)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# test_headings.rb
|
|
2
|
+
# May 15, 2008
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
require "rubygems"
|
|
9
|
+
require "clothblue"
|
|
10
|
+
rescue LoadError
|
|
11
|
+
require "clothblue"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require 'test/unit'
|
|
15
|
+
|
|
16
|
+
class TestClothBlueHeadings < Test::Unit::TestCase
|
|
17
|
+
|
|
18
|
+
HEADING_TEST = [
|
|
19
|
+
["<h1>Heading 1</h1>","# Heading 1 #\n\n"], ["<h2>Heading 2</h2>", "## Heading 2 ##\n\n"],
|
|
20
|
+
["<h3>Heading 3</h3>", "### Heading 3 ###\n\n"], ["<h4>Heading 4</h4>", "#### Heading 4 ####\n\n"],
|
|
21
|
+
["<h5>Heading 5</h5>", "##### Heading 5 #####\n\n"], ["<h6>Heading 6</h6>", "###### Heading 6 ######\n\n"]
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_headings
|
|
26
|
+
HEADING_TEST.each do |html, markdown|
|
|
27
|
+
test_html = ClothBlue.new(html)
|
|
28
|
+
result = test_html.to_markdown
|
|
29
|
+
assert_equal(markdown,result)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
MIST_TEST = [
|
|
34
|
+
["<h1>Heading 1</h1><h2>Heading 2</h2>","# Heading 1 #\n\n## Heading 2 ##\n\n"],
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_mist_headings
|
|
39
|
+
MIST_TEST.each do |html, markdown|
|
|
40
|
+
test_html = ClothBlue.new(html)
|
|
41
|
+
result = test_html.to_markdown
|
|
42
|
+
assert_equal(markdown,result)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
data/test/test_lists.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# test_lists.rb
|
|
2
|
+
# May 15, 2008
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
require "rubygems"
|
|
9
|
+
require "clothblue"
|
|
10
|
+
rescue LoadError
|
|
11
|
+
require "clothblue"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require 'test/unit'
|
|
15
|
+
|
|
16
|
+
class TestClothBlueLists < Test::Unit::TestCase
|
|
17
|
+
|
|
18
|
+
LISTS_TEST = [
|
|
19
|
+
["<ol>",""], ["</ol>","\n\n"], ["<li>","+ "], ["</li>","\n"], ["<ul>", ""], ["</ul>", "\n\n"]
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
def test_lists
|
|
23
|
+
LISTS_TEST.each do |html, markdown|
|
|
24
|
+
test_html = ClothBlue.new(html)
|
|
25
|
+
result = test_html.to_markdown
|
|
26
|
+
assert_equal(markdown,result)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# test_structure.rb
|
|
2
|
+
# May 15, 2008
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
require "rubygems"
|
|
9
|
+
require "clothblue"
|
|
10
|
+
rescue LoadError
|
|
11
|
+
require "clothblue"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require 'test/unit'
|
|
15
|
+
|
|
16
|
+
class TestClothBlueStructures < Test::Unit::TestCase
|
|
17
|
+
|
|
18
|
+
STRUCTURE_TEST = [
|
|
19
|
+
["<blockquote>blockquote</blockquote>","> blockquote\n"],
|
|
20
|
+
["<p>paragraph</p><p>another paragraph</p>", "\n\nparagraph\n\n\n\nanother paragraph\n\n"],
|
|
21
|
+
["HTML page break<br>", "HTML page break\n"], ["XHTML page break<br />", "XHTML page break\n"]
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_structures
|
|
26
|
+
STRUCTURE_TEST.each do |html, markdown|
|
|
27
|
+
test_html = ClothBlue.new(html)
|
|
28
|
+
result = test_html.to_markdown
|
|
29
|
+
assert_equal(markdown,result)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/test/test_tables.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# test_tables.rb
|
|
2
|
+
# May 15, 2008
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
require "rubygems"
|
|
9
|
+
require "clothblue"
|
|
10
|
+
rescue LoadError
|
|
11
|
+
require "clothblue"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require 'test/unit'
|
|
15
|
+
|
|
16
|
+
class TestClothBlueTables < Test::Unit::TestCase
|
|
17
|
+
|
|
18
|
+
TABLES_TEST = [
|
|
19
|
+
["<table><tr><td>name</td><td>age</td><td>sex</td></tr><tr><td>joan</td><td>24</td><td>f</td></tr></table>",
|
|
20
|
+
"\n\n<table><tr><td>name</td><td>age</td><td>sex</td></tr><tr><td>joan</td><td>24</td><td>f</td></tr></table>\n\n"]
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
def test_entities
|
|
24
|
+
TABLES_TEST.each do |html, markdown|
|
|
25
|
+
test_html = ClothBlue.new(html)
|
|
26
|
+
result = test_html.to_markdown
|
|
27
|
+
assert_equal(markdown,result)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: cpjolicoeur-ClothBlue
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Craig P Jolicoeur
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2008-05-14 13:03:28.160028 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: ClothBlue is BlueCloth's evil twin. It converts existing HTML into Markdown format for use with BlueCloth.
|
|
17
|
+
email: cpjolicoeur@gmail.com
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files: []
|
|
23
|
+
|
|
24
|
+
files:
|
|
25
|
+
- README
|
|
26
|
+
- TODO
|
|
27
|
+
- clothblue.gemspec
|
|
28
|
+
- lib/clothblue.rb
|
|
29
|
+
- lib/README.rdoc
|
|
30
|
+
- test/README
|
|
31
|
+
- test/test_entities.rb
|
|
32
|
+
- test/test_formatting.rb
|
|
33
|
+
- test/test_headings.rb
|
|
34
|
+
- test/test_lists.rb
|
|
35
|
+
- test/test_structure.rb
|
|
36
|
+
- test/test_tables.rb
|
|
37
|
+
has_rdoc: true
|
|
38
|
+
homepage: http://github.com/cpjolicoeur/clothblue
|
|
39
|
+
post_install_message:
|
|
40
|
+
rdoc_options:
|
|
41
|
+
- --main
|
|
42
|
+
- lib/README.rdoc
|
|
43
|
+
require_paths:
|
|
44
|
+
- lib
|
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: "0"
|
|
50
|
+
version:
|
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: "0"
|
|
56
|
+
version:
|
|
57
|
+
requirements: []
|
|
58
|
+
|
|
59
|
+
rubyforge_project:
|
|
60
|
+
rubygems_version: 1.0.1
|
|
61
|
+
signing_key:
|
|
62
|
+
specification_version: 2
|
|
63
|
+
summary: HTML to Markdown converter
|
|
64
|
+
test_files:
|
|
65
|
+
- test/test_entities.rb
|
|
66
|
+
- test/test_formatting.rb
|
|
67
|
+
- test/test_headings.rb
|
|
68
|
+
- test/test_lists.rb
|
|
69
|
+
- test/test_structure.rb
|
|
70
|
+
- test/test_tables.rb
|