upmark 0.2.0 → 0.9.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/upmark.rb +12 -3
- data/lib/upmark/errors.rb +12 -1
- data/lib/upmark/parser/xml.rb +33 -20
- data/lib/upmark/transform/markdown.rb +43 -30
- data/lib/upmark/transform/normalise.rb +30 -1
- data/lib/upmark/transform/preprocess.rb +32 -1
- data/spec/acceptance/upmark_spec.rb +161 -54
- data/spec/spec_helper.rb +8 -0
- data/spec/unit/lib/upmark/parser/xml_spec.rb +224 -89
- data/spec/unit/lib/upmark/transform/markdown_spec.rb +89 -17
- metadata +10 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebfa7a03ebe86bf8d70709fe99002518ee9f7237
|
4
|
+
data.tar.gz: be21325fe8ab8cd94d9ba4a4df1fcb0025bfb64b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4eab42d3640a2f9011daf71244c97036f9e92bce80cf351fe9eeda00b1535f0ef5a0471440ec1c4dd9d5c0ac8c76d9c0263661f9c2c6f9d1425a3845296c901
|
7
|
+
data.tar.gz: 3ed9e855887dbab065c586517669657e7c4cb56311b1e5237161111e64853043c2e44097f2bff95b5841ecd5fe3424cd29811940fc07fe8e860472a4ad77b92c
|
data/README.md
CHANGED
data/lib/upmark.rb
CHANGED
@@ -24,11 +24,20 @@ module Upmark
|
|
24
24
|
# The result is either a String or an Array.
|
25
25
|
ast = ast.join if ast.is_a?(Array)
|
26
26
|
|
27
|
+
# Remove trailing whitespace
|
28
|
+
ast.gsub!(/ +$/,'')
|
29
|
+
|
30
|
+
# Compress bullet point lists
|
31
|
+
ast.gsub!(/^•\s*([^•\n]*)\n+(?=•)/,"* #{'\1'}\n")
|
32
|
+
|
27
33
|
# Any more than two consecutive newline characters is superflous.
|
28
|
-
ast
|
34
|
+
ast.gsub!(/\n(\s*\n)+/, "\n\n")
|
35
|
+
|
36
|
+
# Remove other bullet points
|
37
|
+
ast.gsub!(/^•\s*/,"* ")
|
29
38
|
|
30
39
|
ast.strip
|
31
|
-
rescue Parslet::ParseFailed
|
32
|
-
raise Upmark::ParseFailed
|
40
|
+
rescue Parslet::ParseFailed => e
|
41
|
+
raise Upmark::ParseFailed.new('Parse failed', e)
|
33
42
|
end
|
34
43
|
end
|
data/lib/upmark/errors.rb
CHANGED
data/lib/upmark/parser/xml.rb
CHANGED
@@ -10,68 +10,81 @@ module Upmark
|
|
10
10
|
class XML < Parslet::Parser
|
11
11
|
root(:node)
|
12
12
|
|
13
|
-
rule(:node)
|
13
|
+
rule(:node) do
|
14
14
|
(
|
15
|
+
empty_element.as(:empty) |
|
15
16
|
element.as(:element) |
|
16
17
|
text.as(:text)
|
17
18
|
).repeat(0)
|
18
|
-
|
19
|
+
end
|
19
20
|
|
20
|
-
rule(:
|
21
|
+
rule(:empty_element) do
|
22
|
+
start_tag.as(:start_tag) >>
|
23
|
+
match(/\s+/) >>
|
24
|
+
end_tag.as(:end_tag)
|
25
|
+
end
|
26
|
+
|
27
|
+
rule(:element) do
|
28
|
+
empty_br.as(:empty_tag) |
|
21
29
|
(
|
22
30
|
start_tag.as(:start_tag) >>
|
23
31
|
node.as(:children) >>
|
24
32
|
end_tag.as(:end_tag)
|
25
33
|
) |
|
26
34
|
empty_tag.as(:empty_tag)
|
27
|
-
|
35
|
+
end
|
28
36
|
|
29
|
-
rule(:text)
|
37
|
+
rule(:text) do
|
38
|
+
match(/\A[\s\n\t ]+\Z/m).absent? >> # ignore entirely empty strings
|
30
39
|
match(/[^<>]/).repeat(1)
|
31
|
-
|
40
|
+
end
|
32
41
|
|
33
|
-
rule(:start_tag)
|
42
|
+
rule(:start_tag) do
|
34
43
|
str('<') >>
|
35
44
|
name.as(:name) >>
|
36
45
|
(space >> attribute).repeat.as(:attributes) >>
|
37
46
|
space? >>
|
38
47
|
str('>')
|
39
|
-
|
48
|
+
end
|
40
49
|
|
41
|
-
rule(:end_tag)
|
50
|
+
rule(:end_tag) do
|
42
51
|
str('</') >>
|
43
52
|
name.as(:name) >>
|
44
53
|
space? >>
|
45
54
|
str('>')
|
46
|
-
|
55
|
+
end
|
56
|
+
|
57
|
+
rule(:empty_br) do
|
58
|
+
str('<') >> space? >> str('br').as(:name) >> space? >> str('>')
|
59
|
+
end
|
47
60
|
|
48
|
-
rule(:empty_tag)
|
61
|
+
rule(:empty_tag) do
|
49
62
|
str('<') >>
|
50
63
|
name.as(:name) >>
|
51
64
|
(space >> attribute).repeat.as(:attributes) >>
|
52
65
|
space? >>
|
53
66
|
str('/>')
|
54
|
-
|
67
|
+
end
|
55
68
|
|
56
|
-
rule(:name)
|
69
|
+
rule(:name) do
|
57
70
|
match(/[a-zA-Z_:]/) >> match(/[\w:\.-]/).repeat
|
58
|
-
|
71
|
+
end
|
59
72
|
|
60
|
-
rule(:attribute)
|
73
|
+
rule(:attribute) do
|
61
74
|
name.as(:name) >>
|
62
75
|
str('=') >> (
|
63
76
|
(str('"') >> double_quoted_attribute_value.as(:value) >> str('"')) | # double quotes
|
64
77
|
(str("'") >> single_quoted_attribute_value.as(:value) >> str("'")) # single quotes
|
65
78
|
)
|
66
|
-
|
79
|
+
end
|
67
80
|
|
68
|
-
rule(:double_quoted_attribute_value)
|
81
|
+
rule(:double_quoted_attribute_value) do
|
69
82
|
(str('"').absent? >> (match(/[^<&]/) | entity_ref)).repeat
|
70
|
-
|
83
|
+
end
|
71
84
|
|
72
|
-
rule(:single_quoted_attribute_value)
|
85
|
+
rule(:single_quoted_attribute_value) do
|
73
86
|
(str("'").absent? >> (match(/[^<&]/) | entity_ref)).repeat
|
74
|
-
|
87
|
+
end
|
75
88
|
|
76
89
|
rule(:entity_ref) { match("&") >> name >> match(";") }
|
77
90
|
|
@@ -7,19 +7,49 @@ module Upmark
|
|
7
7
|
|
8
8
|
rule(text: simple(:value)) { value.to_s }
|
9
9
|
|
10
|
+
# Pass all unmatched elements through.
|
11
|
+
rule(
|
12
|
+
element: {
|
13
|
+
name: simple(:name),
|
14
|
+
attributes: subtree(:attributes),
|
15
|
+
children: sequence(:children),
|
16
|
+
ignore: simple(:ignore)
|
17
|
+
}
|
18
|
+
) do |element|
|
19
|
+
attributes = map_attributes_subtree(element[:attributes])
|
20
|
+
children = element[:children].join
|
21
|
+
name = element[:name]
|
22
|
+
|
23
|
+
attributes_list =
|
24
|
+
if attributes.any?
|
25
|
+
" " + attributes.map {|name, value| %Q{#{name}="#{value}"} }.join(" ")
|
26
|
+
else
|
27
|
+
""
|
28
|
+
end
|
29
|
+
|
30
|
+
if children.empty?
|
31
|
+
%Q{<#{name}#{attributes_list} />}
|
32
|
+
else
|
33
|
+
%Q{<#{name}#{attributes_list}>#{children}</#{name}>}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
10
37
|
def self.text(element)
|
11
|
-
element[:children].join.gsub(/(\n)+/, '\1')
|
38
|
+
element[:children].join.gsub(/(\n)[\n ]+/, '\1')
|
12
39
|
end
|
13
40
|
|
14
41
|
element(:p) {|element| "#{text(element)}\n\n" }
|
15
42
|
element(:h1) {|element| "# #{text(element)}" }
|
16
43
|
element(:h2) {|element| "## #{text(element)}" }
|
17
44
|
element(:h3) {|element| "### #{text(element)}" }
|
45
|
+
element(:h4) {|element| "#### #{text(element)}" }
|
46
|
+
element(:h5) {|element| "##### #{text(element)}" }
|
47
|
+
element(:h6) {|element| "###### #{text(element)}" }
|
18
48
|
element(:li) {|element| "#{text(element)}" }
|
19
49
|
|
20
50
|
element(:ul) do |element|
|
21
51
|
children = element[:children].map {|value| value.strip != "" ? value : nil }.compact
|
22
|
-
children.map {|value| "* #{value}\n" }
|
52
|
+
children.map {|value| "* #{value.gsub(/^\s*•\s*/,'')}\n" }
|
23
53
|
end
|
24
54
|
|
25
55
|
element(:ol) do |element|
|
@@ -32,7 +62,11 @@ module Upmark
|
|
32
62
|
href = attributes[:href]
|
33
63
|
title = attributes[:title]
|
34
64
|
|
35
|
-
|
65
|
+
if /^(?:http|mailto)/ =~ href
|
66
|
+
%Q{[#{text(element)}](#{href} "#{title}")}
|
67
|
+
else
|
68
|
+
text(element)
|
69
|
+
end
|
36
70
|
end
|
37
71
|
|
38
72
|
element(:img) do |element|
|
@@ -41,40 +75,19 @@ module Upmark
|
|
41
75
|
title = attributes[:title]
|
42
76
|
alt_text = attributes[:alt]
|
43
77
|
|
44
|
-
|
78
|
+
if /^http/ =~ href
|
79
|
+
%Q{}
|
80
|
+
else
|
81
|
+
"#{alt_text || title}"
|
82
|
+
end
|
45
83
|
end
|
46
84
|
|
47
85
|
element(:b, :strong) {|element| "**#{text(element)}**" }
|
48
86
|
element(:i, :em) {|element| "*#{text(element)}*" }
|
49
87
|
|
50
88
|
element(:br) { "\n" }
|
89
|
+
rule(element: { name: "br"}) { "\n" }
|
51
90
|
|
52
|
-
# Pass all unmatched elements through.
|
53
|
-
rule(
|
54
|
-
element: {
|
55
|
-
name: simple(:name),
|
56
|
-
attributes: subtree(:attributes),
|
57
|
-
children: sequence(:children),
|
58
|
-
ignore: simple(:ignore)
|
59
|
-
}
|
60
|
-
) do |element|
|
61
|
-
attributes = map_attributes_subtree(element[:attributes])
|
62
|
-
children = element[:children].join
|
63
|
-
name = element[:name]
|
64
|
-
|
65
|
-
attributes_list =
|
66
|
-
if attributes.any?
|
67
|
-
" " + attributes.map {|name, value| %Q{#{name}="#{value}"} }.join(" ")
|
68
|
-
else
|
69
|
-
""
|
70
|
-
end
|
71
|
-
|
72
|
-
if children.empty?
|
73
|
-
%Q{<#{name}#{attributes_list} />}
|
74
|
-
else
|
75
|
-
%Q{<#{name}#{attributes_list}>#{children}</#{name}>}
|
76
|
-
end
|
77
|
-
end
|
78
91
|
end
|
79
92
|
end
|
80
93
|
end
|
@@ -3,13 +3,26 @@ module Upmark
|
|
3
3
|
# A transform class withich normalises start/end/empty tags into the
|
4
4
|
# same structure.
|
5
5
|
class Normalise < Parslet::Transform
|
6
|
+
|
7
|
+
rule(element: subtree(:invalid)) do
|
8
|
+
raise Upmark::ParseFailed.new('Invalid parse result', nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Strip empty tags
|
12
|
+
rule(empty: subtree(:invalid)) do
|
13
|
+
' '
|
14
|
+
end
|
15
|
+
|
6
16
|
rule(
|
7
17
|
element: {
|
8
18
|
start_tag: {name: simple(:name), attributes: subtree(:attributes)},
|
9
|
-
end_tag: {name: simple(:
|
19
|
+
end_tag: {name: simple(:end_tag_name)},
|
10
20
|
children: subtree(:children)
|
11
21
|
}
|
12
22
|
) do
|
23
|
+
unless name == end_tag_name
|
24
|
+
raise Upmark::ParseFailed.new('Mismatched tags', nil)
|
25
|
+
end
|
13
26
|
{
|
14
27
|
element: {
|
15
28
|
name: name,
|
@@ -20,6 +33,21 @@ module Upmark
|
|
20
33
|
}
|
21
34
|
end
|
22
35
|
|
36
|
+
rule(
|
37
|
+
element: {
|
38
|
+
empty_tag: { name: simple(:name) }
|
39
|
+
}
|
40
|
+
) do
|
41
|
+
{
|
42
|
+
element: {
|
43
|
+
name: name,
|
44
|
+
attributes: [],
|
45
|
+
children: [],
|
46
|
+
ignore: false
|
47
|
+
}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
23
51
|
rule(
|
24
52
|
element: {
|
25
53
|
empty_tag: {name: simple(:name), attributes: subtree(:attributes)}
|
@@ -34,6 +62,7 @@ module Upmark
|
|
34
62
|
}
|
35
63
|
}
|
36
64
|
end
|
65
|
+
|
37
66
|
end
|
38
67
|
end
|
39
68
|
end
|
@@ -7,7 +7,7 @@ module Upmark
|
|
7
7
|
class Preprocess < Parslet::Transform
|
8
8
|
include TransformHelpers
|
9
9
|
|
10
|
-
element(:div, :
|
10
|
+
element(:div, :pre) do |element|
|
11
11
|
{
|
12
12
|
element: {
|
13
13
|
name: element[:name],
|
@@ -17,6 +17,37 @@ module Upmark
|
|
17
17
|
}
|
18
18
|
}
|
19
19
|
end
|
20
|
+
|
21
|
+
element(:span) do |element|
|
22
|
+
element[:children]
|
23
|
+
end
|
24
|
+
|
25
|
+
# table content elements are stripped ignoring their spacing
|
26
|
+
element(:table, :thead, :tbody, :tfoot) do |element|
|
27
|
+
element[:children].reject! do |c|
|
28
|
+
Hash === c && c[:text].to_s =~ /\A[\n ]*\Z/m
|
29
|
+
end
|
30
|
+
element[:children]
|
31
|
+
end
|
32
|
+
|
33
|
+
# table content elements are stripped
|
34
|
+
element(:td, :th) do |element|
|
35
|
+
element[:children]
|
36
|
+
end
|
37
|
+
|
38
|
+
# table rows are treated as 'paragraph' blocks
|
39
|
+
element(:tr) do |element|
|
40
|
+
element[:children]
|
41
|
+
.select { |c| Array === c }
|
42
|
+
.map do |children|
|
43
|
+
children.map do |child|
|
44
|
+
if child[:text]
|
45
|
+
child[:text].to_s.gsub!(/^\n */,'')
|
46
|
+
end
|
47
|
+
child
|
48
|
+
end + ["\n"]
|
49
|
+
end + ["\n"]
|
50
|
+
end
|
20
51
|
end
|
21
52
|
end
|
22
53
|
end
|
@@ -1,57 +1,102 @@
|
|
1
|
-
|
1
|
+
RSpec.describe Upmark, ".convert" do
|
2
|
+
RSpec::Matchers.define :convert_to do |expected|
|
3
|
+
match do
|
4
|
+
actual == expected
|
5
|
+
end
|
2
6
|
|
3
|
-
|
4
|
-
|
7
|
+
def actual
|
8
|
+
@converted_actual ||= Upmark.convert(@actual)
|
9
|
+
end
|
5
10
|
|
6
|
-
|
7
|
-
|
8
|
-
<p><a href="http://helvetica.com/" title="art party organic">messenger <strong>bag</strong> skateboard</a></p>
|
9
|
-
HTML
|
11
|
+
diffable
|
12
|
+
end
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
+
context "<a>" do
|
15
|
+
specify 'converts to []()' do
|
16
|
+
expect(<<-HTML.strip
|
17
|
+
<p><a href="http://helvetica.com/" title="art party organic">messenger <strong>bag</strong> skateboard</a></p>
|
18
|
+
HTML
|
19
|
+
).to convert_to <<-MD.strip
|
20
|
+
[messenger **bag** skateboard](http://helvetica.com/ "art party organic")
|
21
|
+
MD
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
16
25
|
context "<a> hard" do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
26
|
+
specify 'converts as []()' do
|
27
|
+
expect(<<-HTML.strip
|
28
|
+
<p><a href="http://jobs.latrobe.edu.au/jobDetails.asp?sJobIDs=545808&sKeywords=business">Manager, Business Solutions</a></p>
|
29
|
+
HTML
|
30
|
+
).to convert_to <<-MD.strip
|
22
31
|
[Manager, Business Solutions](http://jobs.latrobe.edu.au/jobDetails.asp?sJobIDs=545808&sKeywords=business "")
|
23
|
-
|
32
|
+
MD
|
33
|
+
end
|
24
34
|
end
|
25
35
|
|
26
36
|
context "<img>" do
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
it { should == <<-MD.strip }
|
37
|
+
specify 'converts as ![]()' do
|
38
|
+
expect(<<-HTML.strip
|
39
|
+
<img src="http://helvetica.com/image.gif" title="art party organic" alt="messenger bag skateboard" />
|
40
|
+
HTML
|
41
|
+
).to convert_to <<-MD.strip
|
33
42
|

|
34
|
-
|
43
|
+
MD
|
44
|
+
end
|
35
45
|
end
|
36
46
|
|
37
47
|
context "<p>" do
|
38
|
-
|
48
|
+
specify 'converts as plaintext' do
|
49
|
+
expect(<<-HTML.strip
|
50
|
+
<p>• Bullet 1</p>
|
51
|
+
<p>• Bullet 2</p>
|
39
52
|
<p>messenger <strong>bag</strong> skateboard</p>
|
40
53
|
|
41
54
|
<p>art party<br />
|
42
55
|
organic</p>
|
43
|
-
HTML
|
44
56
|
|
45
|
-
|
57
|
+
<p>art party<br>
|
58
|
+
organic</p>
|
59
|
+
|
60
|
+
<p> </p>
|
61
|
+
<p><strong> </strong></p>
|
62
|
+
|
63
|
+
<p>• Bullet 3</p>
|
64
|
+
<p>• Bullet 4</p>
|
65
|
+
<p>• Bullet 5</p>
|
66
|
+
<p>• Bullet 6</p>
|
67
|
+
<p>• Bullet 7</p>
|
68
|
+
<p>Something else</p>
|
69
|
+
HTML
|
70
|
+
).to convert_to <<-MD.strip
|
71
|
+
* Bullet 1
|
72
|
+
* Bullet 2
|
73
|
+
|
46
74
|
messenger **bag** skateboard
|
47
75
|
|
48
76
|
art party
|
49
77
|
organic
|
50
|
-
|
78
|
+
|
79
|
+
art party
|
80
|
+
organic
|
81
|
+
|
82
|
+
* Bullet 3
|
83
|
+
* Bullet 4
|
84
|
+
* Bullet 5
|
85
|
+
* Bullet 6
|
86
|
+
* Bullet 7
|
87
|
+
|
88
|
+
Something else
|
89
|
+
MD
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'converts paragraph utf-8 bullet points to a markdown list' do
|
93
|
+
expect("<p>• Bullet 1</p><p>• Bullet 2</p>").to convert_to "* Bullet 1\n* Bullet 2"
|
94
|
+
end
|
51
95
|
end
|
52
96
|
|
53
97
|
context "<ul>" do
|
54
|
-
|
98
|
+
specify 'converts as list' do
|
99
|
+
expect(<<-HTML.strip
|
55
100
|
<ul>
|
56
101
|
<li>messenger</li>
|
57
102
|
<li><strong>bag</strong></li>
|
@@ -63,9 +108,13 @@ organic
|
|
63
108
|
<li><p><strong>bag</strong></p></li>
|
64
109
|
<li><p>skateboard</p></li>
|
65
110
|
</ul>
|
66
|
-
HTML
|
67
111
|
|
68
|
-
|
112
|
+
<ul>
|
113
|
+
<li>• Bullet 1</li>
|
114
|
+
<li>• Bullet 2</li>
|
115
|
+
</ul>
|
116
|
+
HTML
|
117
|
+
).to convert_to <<-MD.strip
|
69
118
|
* messenger
|
70
119
|
* **bag**
|
71
120
|
* skateboard
|
@@ -75,11 +124,16 @@ organic
|
|
75
124
|
* **bag**
|
76
125
|
|
77
126
|
* skateboard
|
78
|
-
|
127
|
+
|
128
|
+
* Bullet 1
|
129
|
+
* Bullet 2
|
130
|
+
MD
|
131
|
+
end
|
79
132
|
end
|
80
133
|
|
81
134
|
context "<ol>" do
|
82
|
-
|
135
|
+
specify 'converts as numbered list' do
|
136
|
+
expect(<<-HTML.strip
|
83
137
|
<ol>
|
84
138
|
<li>messenger</li>
|
85
139
|
<li><strong>bag</strong></li>
|
@@ -91,9 +145,8 @@ organic
|
|
91
145
|
<li><p><strong>bag</strong></p></li>
|
92
146
|
<li><p>skateboard</p></li>
|
93
147
|
</ol>
|
94
|
-
|
95
|
-
|
96
|
-
it { should == <<-MD.strip }
|
148
|
+
HTML
|
149
|
+
).to convert_to <<-MD.strip
|
97
150
|
1. messenger
|
98
151
|
2. **bag**
|
99
152
|
3. skateboard
|
@@ -103,21 +156,29 @@ organic
|
|
103
156
|
2. **bag**
|
104
157
|
|
105
158
|
3. skateboard
|
106
|
-
|
159
|
+
MD
|
160
|
+
end
|
107
161
|
end
|
108
162
|
|
109
|
-
context "<h1>" do
|
110
|
-
|
163
|
+
context "<h1>, <h2>, <h3>, <h4>, <h5>, <h6>" do
|
164
|
+
specify 'converts as #' do
|
165
|
+
expect(<<-HTML.strip
|
111
166
|
<h1>messenger bag skateboard</h1>
|
112
167
|
<h2>messenger bag skateboard</h2>
|
113
168
|
<h3>messenger bag skateboard</h3>
|
114
|
-
|
115
|
-
|
116
|
-
|
169
|
+
<h4>messenger bag skateboard</h4>
|
170
|
+
<h5>messenger bag skateboard</h5>
|
171
|
+
<h6>messenger bag skateboard</h6>
|
172
|
+
HTML
|
173
|
+
).to convert_to <<-MD.strip
|
117
174
|
# messenger bag skateboard
|
118
175
|
## messenger bag skateboard
|
119
176
|
### messenger bag skateboard
|
120
|
-
|
177
|
+
#### messenger bag skateboard
|
178
|
+
##### messenger bag skateboard
|
179
|
+
###### messenger bag skateboard
|
180
|
+
MD
|
181
|
+
end
|
121
182
|
end
|
122
183
|
|
123
184
|
context "block-level elements" do
|
@@ -127,25 +188,52 @@ organic
|
|
127
188
|
<div id="tofu" class="art party">messenger <strong>bag</strong> skateboard</div>
|
128
189
|
HTML
|
129
190
|
|
130
|
-
|
191
|
+
specify 'are left alone' do
|
192
|
+
expect(html).to convert_to html
|
193
|
+
end
|
131
194
|
end
|
132
195
|
|
133
196
|
context "<table>" do
|
134
197
|
let(:html) { <<-HTML.strip }
|
135
198
|
<table>
|
136
199
|
<tr>
|
137
|
-
<td>messenger</td>
|
200
|
+
<td><p><strong>messenger</strong></p></td>
|
201
|
+
<td><p>bag</p></td>
|
202
|
+
</tr>
|
203
|
+
<tr>
|
204
|
+
<td><p>messenger</p></td>
|
205
|
+
<td><p><strong>bag</strong></p></td>
|
138
206
|
</tr>
|
139
207
|
<tr>
|
140
|
-
<td
|
208
|
+
<td>skateboarding</td>
|
209
|
+
<td><p>is cool with all the kids<br/>
|
210
|
+
or something</p></td>
|
141
211
|
</tr>
|
142
212
|
<tr>
|
143
|
-
<td>
|
213
|
+
<td><strong>Messenger bags</strong></td>
|
214
|
+
<td>are in with the hipsters though.</td>
|
144
215
|
</tr>
|
145
216
|
</table>
|
146
217
|
HTML
|
147
218
|
|
148
|
-
|
219
|
+
specify 'is converted to paragraphs' do
|
220
|
+
expect(html).to convert_to <<-MD.strip
|
221
|
+
**messenger**
|
222
|
+
|
223
|
+
bag
|
224
|
+
|
225
|
+
messenger
|
226
|
+
|
227
|
+
**bag**
|
228
|
+
|
229
|
+
skateboarding
|
230
|
+
is cool with all the kids
|
231
|
+
or something
|
232
|
+
|
233
|
+
**Messenger bags**
|
234
|
+
are in with the hipsters though.
|
235
|
+
MD
|
236
|
+
end
|
149
237
|
end
|
150
238
|
|
151
239
|
context "<pre>" do
|
@@ -157,22 +245,31 @@ organic
|
|
157
245
|
</pre>
|
158
246
|
HTML
|
159
247
|
|
160
|
-
|
248
|
+
specify 'are left alone' do
|
249
|
+
expect(html).to convert_to html
|
250
|
+
end
|
161
251
|
end
|
162
252
|
end
|
163
253
|
|
164
|
-
context "span
|
165
|
-
|
166
|
-
|
254
|
+
context "<span> elements" do
|
255
|
+
specify 'are stripped' do
|
256
|
+
expect(<<-HTML.strip
|
167
257
|
<span>messenger <strong>bag</strong> skateboard</span>
|
168
258
|
HTML
|
169
|
-
|
170
|
-
|
171
|
-
<span>messenger **bag** skateboard</span>
|
259
|
+
).to convert_to <<-MD.strip
|
260
|
+
messenger **bag** skateboard
|
172
261
|
MD
|
173
262
|
end
|
174
263
|
end
|
175
264
|
|
265
|
+
context "plain text" do
|
266
|
+
it 'containing plain bullet points converts to markdown' do
|
267
|
+
expect(
|
268
|
+
"• Bullet 1\n• Bullet 2\n"
|
269
|
+
).to convert_to "* Bullet 1\n* Bullet 2"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
176
273
|
context "unbalanced elements" do
|
177
274
|
let(:html) { "<span><span>foo</span>" }
|
178
275
|
|
@@ -182,4 +279,14 @@ organic
|
|
182
279
|
}.to raise_error(Upmark::ParseFailed)
|
183
280
|
end
|
184
281
|
end
|
282
|
+
|
283
|
+
context "unbalanced elements" do
|
284
|
+
let(:html) { "<p>foo</b>" }
|
285
|
+
|
286
|
+
it "should raise an exception" do
|
287
|
+
expect {
|
288
|
+
Upmark.convert(html)
|
289
|
+
}.to raise_error(Upmark::ParseFailed)
|
290
|
+
end
|
291
|
+
end
|
185
292
|
end
|