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 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.0'
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
- remark_children(scope).join("\n\n")
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.to_s =~ /\A\s*\Z/
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
- remark_inline(elem)
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.gsub(/^/, ' '*4)
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
- "`#{elem.inner_text}`"
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").gsub(/^/, '> ')
95
+ remark_children(elem).join("\n\n").indent('> ')
87
96
  when 'br'
88
- ' ' + elem.inner_html
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(/\s{2,}/, ' ')
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
- remark_children(list).map do |item|
107
- if unordered
108
- marker + ' ' + item
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
- (marker += 1).to_s + '. ' + item
124
+ current + ' ' + item
111
125
  end
112
- end.join("\n")
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 &lt;bar&gt;\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>&lt;tags&gt;</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 == 'Foo bar'
98
- remark("<p>Foo<br>\nbar <code>baz</code></p>").should == 'Foo bar `baz`'
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>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mislav-remark
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Mislav Marohni\xC4\x87"