mislav-remark 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/remark.rb +55 -13
- data/spec/remark_spec.rb +37 -3
- data/spec/sample.html +16 -11
- metadata +1 -1
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ task :gemspec do
|
|
8
8
|
gem.authors = ["Mislav Marohnić"]
|
9
9
|
gem.has_rdoc = false
|
10
10
|
|
11
|
-
gem.version = '0.2.
|
11
|
+
gem.version = '0.2.1'
|
12
12
|
gem.files = FileList['Rakefile', '{bin,lib,rails,spec}/**/*', 'README*', 'LICENSE*'] & `git ls-files`.split("\n")
|
13
13
|
gem.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
14
14
|
end
|
data/lib/remark.rb
CHANGED
@@ -6,7 +6,7 @@ class Remark
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def to_markdown
|
9
|
-
|
9
|
+
remark_block(scope)
|
10
10
|
end
|
11
11
|
|
12
12
|
def scope
|
@@ -23,6 +23,7 @@ class Remark
|
|
23
23
|
end
|
24
24
|
|
25
25
|
IGNORE = %w(script head style)
|
26
|
+
BLOCK = %w(p blockquote h1 h2 h3 h4 h5 h6 pre)
|
26
27
|
|
27
28
|
private
|
28
29
|
|
@@ -37,6 +38,12 @@ class Remark
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
41
|
+
def remark_block(elem)
|
42
|
+
remark_children(elem).
|
43
|
+
reject { |item| item.blank? }.
|
44
|
+
join("\n\n")
|
45
|
+
end
|
46
|
+
|
40
47
|
def remark_children(node)
|
41
48
|
remarked = []
|
42
49
|
node.children.each do |item|
|
@@ -48,7 +55,7 @@ class Remark
|
|
48
55
|
|
49
56
|
def remark_item(item)
|
50
57
|
if item.text?
|
51
|
-
item.to_s.gsub(/\n+/, ' ') unless item.
|
58
|
+
item.to_s.gsub(/\n+/, ' ') unless item.blank?
|
52
59
|
elsif item.elem?
|
53
60
|
if IGNORE.include?(item.name)
|
54
61
|
nil
|
@@ -69,23 +76,25 @@ class Remark
|
|
69
76
|
when 'ul', 'ol'
|
70
77
|
remark_list(elem)
|
71
78
|
when 'li'
|
72
|
-
|
79
|
+
elem.children.any? { |e| e.elem? and BLOCK.include?(e.name) } ?
|
80
|
+
remark_block(elem).indent : remark_inline(elem)
|
73
81
|
when 'pre'
|
74
|
-
elem.inner_text.
|
82
|
+
elem.inner_text.indent
|
75
83
|
when 'em'
|
76
84
|
"_#{elem.inner_text}_"
|
77
85
|
when 'strong'
|
78
86
|
"**#{elem.inner_text}**"
|
79
87
|
when 'code'
|
80
|
-
|
88
|
+
code = elem.inner_text
|
89
|
+
code.index('`') ? "`` #{code} ``" : "`#{code}`"
|
81
90
|
when 'a'
|
82
91
|
remark_link(elem.inner_html, elem.attributes['href'], elem.attributes['title'])
|
83
92
|
when 'img'
|
84
93
|
'!' + remark_link(elem.attributes['alt'], elem.attributes['src'], elem.attributes['title'])
|
85
94
|
when 'blockquote'
|
86
|
-
remark_children(elem).join("\n\n").
|
95
|
+
remark_children(elem).join("\n\n").indent('> ')
|
87
96
|
when 'br'
|
88
|
-
|
97
|
+
" \n" + elem.inner_html
|
89
98
|
else
|
90
99
|
elem
|
91
100
|
end
|
@@ -97,18 +106,51 @@ class Remark
|
|
97
106
|
end
|
98
107
|
|
99
108
|
def remark_inline(elem)
|
100
|
-
remark_children(elem).join('').gsub(
|
109
|
+
remark_children(elem).join('').strip.gsub(/ {2,}(?!\n)/, ' ').gsub(/(\n) +/, '\1')
|
101
110
|
end
|
102
111
|
|
103
112
|
def remark_list(list)
|
104
113
|
unordered = list.name == 'ul'
|
105
114
|
marker = unordered ? '*' : 0
|
106
|
-
|
107
|
-
|
108
|
-
|
115
|
+
nested = false
|
116
|
+
|
117
|
+
items = remark_children(list).map do |item|
|
118
|
+
current = unordered ? marker : "#{marker += 1}."
|
119
|
+
if item =~ /\A\s/
|
120
|
+
nested = true
|
121
|
+
item[0, current.length] = current
|
122
|
+
item
|
109
123
|
else
|
110
|
-
|
124
|
+
current + ' ' + item
|
111
125
|
end
|
112
|
-
end
|
126
|
+
end
|
127
|
+
|
128
|
+
items.join("\n" * (nested ? 2 : 1))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
Object.class_eval do
|
133
|
+
def blank?() false end
|
134
|
+
end
|
135
|
+
|
136
|
+
NilClass.class_eval do
|
137
|
+
def blank?() true end
|
138
|
+
end
|
139
|
+
|
140
|
+
String.class_eval do
|
141
|
+
def blank?
|
142
|
+
self.empty? or !!(self =~ /\A\s+\Z/)
|
143
|
+
end
|
144
|
+
|
145
|
+
def squish
|
146
|
+
self.strip.gsub!(/\s+/, ' ')
|
113
147
|
end
|
148
|
+
|
149
|
+
def indent(with = ' ' * 4)
|
150
|
+
self.gsub(/^/, with)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
Hpricot::Text.class_eval do
|
155
|
+
def blank?() to_s.blank? end
|
114
156
|
end
|
data/spec/remark_spec.rb
CHANGED
@@ -48,6 +48,25 @@ describe Remark do
|
|
48
48
|
HTML
|
49
49
|
end
|
50
50
|
|
51
|
+
it "should strip excess whitespace" do
|
52
|
+
remark(<<-HTML).should == "Foo bar"
|
53
|
+
<p>
|
54
|
+
Foo
|
55
|
+
bar
|
56
|
+
</p>
|
57
|
+
HTML
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should strip whitespace in text nodes between main content" do
|
61
|
+
pending
|
62
|
+
remark(<<-HTML).should == "Foo\n\nbar\n\nBaz"
|
63
|
+
<p>Foo</p>
|
64
|
+
|
65
|
+
bar
|
66
|
+
<p>Baz</p>
|
67
|
+
HTML
|
68
|
+
end
|
69
|
+
|
51
70
|
it "should support lists" do
|
52
71
|
remark(<<-HTML).should == "* foo\n* bar"
|
53
72
|
<ul>
|
@@ -64,6 +83,15 @@ describe Remark do
|
|
64
83
|
HTML
|
65
84
|
end
|
66
85
|
|
86
|
+
it "should support lists with nested content" do
|
87
|
+
remark(<<-HTML).should == "* foo\n \n bar\n\n* baz"
|
88
|
+
<ul>
|
89
|
+
<li><p>foo</p><p>bar</p></li>
|
90
|
+
<li><p>baz</p></li>
|
91
|
+
</ul>
|
92
|
+
HTML
|
93
|
+
end
|
94
|
+
|
67
95
|
it "should support preformatted blocks" do
|
68
96
|
remark("<pre>def foo\n bar\nend</pre>").should == " def foo\n bar\n end"
|
69
97
|
remark("<pre><code>def foo\n <bar>\nend</code></pre>").should == " def foo\n <bar>\n end"
|
@@ -72,11 +100,16 @@ describe Remark do
|
|
72
100
|
it "should remark inline elements" do
|
73
101
|
remark("<p>I'm so <strong>strong</strong></p>").should == "I'm so **strong**"
|
74
102
|
remark("<p>I'm so <em>emo</em></p>").should == "I'm so _emo_"
|
75
|
-
remark("<p>Write more <code>code</code></p>").should == "Write more `code`"
|
76
103
|
remark("<ul><li><em>Inline</em> stuff in <strong>lists</strong></li></ul>").should == "* _Inline_ stuff in **lists**"
|
77
104
|
remark("<h1>Headings <em>too</em></h1>").should == '# Headings _too_'
|
78
105
|
end
|
79
106
|
|
107
|
+
it "should remark inline code" do
|
108
|
+
remark("<p>Write more <code>code</code></p>").should == "Write more `code`"
|
109
|
+
remark("<p>Even with <code>`backticks`</code></p>").should == "Even with `` `backticks` ``"
|
110
|
+
remark("<p>Or HTML <code><tags></code></p>").should == "Or HTML `<tags>`"
|
111
|
+
end
|
112
|
+
|
80
113
|
it "should support hyperlinks" do
|
81
114
|
remark("<p>Click <a href='http://mislav.uniqpath.com'>here</a></p>").should ==
|
82
115
|
"Click [here](http://mislav.uniqpath.com)"
|
@@ -94,8 +127,9 @@ describe Remark do
|
|
94
127
|
end
|
95
128
|
|
96
129
|
it "should not have BR ruin all the fun" do
|
97
|
-
remark("<p>Foo<br>bar</p>").should ==
|
98
|
-
remark("<p>Foo<br>\nbar <code>baz</code></p>").should ==
|
130
|
+
remark("<p>Foo<br>bar</p>").should == "Foo \nbar"
|
131
|
+
remark("<p>Foo<br>\nbar <code>baz</code></p>").should == "Foo \nbar `baz`"
|
132
|
+
remark("<p>Foo</p><br><p>Bar</p>").should == "Foo\n\nBar"
|
99
133
|
end
|
100
134
|
|
101
135
|
it "should scope to the most likely element that holds content" do
|
data/spec/sample.html
CHANGED
@@ -26,6 +26,19 @@ Markdown doesn't have a syntax for them.</p>
|
|
26
26
|
<li>ordered or unordered.</li>
|
27
27
|
</ul>
|
28
28
|
|
29
|
+
<ol>
|
30
|
+
<li><p>Paragraphs in list items</p></li>
|
31
|
+
<li><p>Make them have one blank line between them in Markdown</p></li>
|
32
|
+
<li>
|
33
|
+
<p>Some list items even have multiple paragraphs</p>
|
34
|
+
<p>That shouldn't be too hard to do … right?</p>
|
35
|
+
<pre>code blocks too</pre>
|
36
|
+
</li>
|
37
|
+
</ol>
|
38
|
+
|
39
|
+
<p>Remark supports BR elements in paragraphs,<br>
|
40
|
+
although people tend to abuse them.</p>
|
41
|
+
|
29
42
|
<pre><code>And who would forget
|
30
43
|
Preformatted code blocks :)</code></pre>
|
31
44
|
|
@@ -33,16 +46,8 @@ Preformatted code blocks :)</code></pre>
|
|
33
46
|
|
34
47
|
<blockquote>
|
35
48
|
<p>I think</p>
|
36
|
-
|
37
49
|
<p>therefore I am</p>
|
50
|
+
<blockquote>
|
51
|
+
<p>Nested blockquotes</p>
|
52
|
+
</blockquote>
|
38
53
|
</blockquote>
|
39
|
-
|
40
|
-
<h2>TODO</h2>
|
41
|
-
|
42
|
-
<p>Remark should probably support BR elements in paragraphs,<br>
|
43
|
-
although people tend to abuse them.</p>
|
44
|
-
|
45
|
-
<div class="content">
|
46
|
-
<p>What to do with pieces of content inside wrapper elements,
|
47
|
-
like DIV, is still undecided.</p>
|
48
|
-
</div>
|