reverse_markdown 0.0.1 → 0.1.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.
Files changed (2) hide show
  1. data/lib/reverse_markdown.rb +37 -39
  2. metadata +19 -3
@@ -1,4 +1,4 @@
1
- require 'rexml/document'
1
+ require 'nokogiri'
2
2
 
3
3
  # reverse markdown for ruby
4
4
  # author: JO
@@ -13,6 +13,7 @@ require 'rexml/document'
13
13
  # -
14
14
 
15
15
  class ReverseMarkdown
16
+ attr_reader :errors
16
17
 
17
18
  # set basic variables:
18
19
  # - @li_counter: numbering list item (li) tags in an ordered list (ol)
@@ -33,9 +34,8 @@ class ReverseMarkdown
33
34
  # To garantuee well-formed xml for REXML a <root> element will be added, but has no effect.
34
35
  # After parsing all elements, the 'reference style'-links will be inserted.
35
36
  def parse_string(string)
36
- doc = REXML::Document.new("<root>\n"+string+"\n</root>")
37
- parse_element(doc.root, :none)
38
- insert_links()
37
+ parse_element(Nokogiri::HTML.fragment(string))
38
+ insert_links
39
39
  @output
40
40
  end
41
41
 
@@ -45,7 +45,7 @@ class ReverseMarkdown
45
45
  # 3a. if element only contains text, handle it like a text node
46
46
  # 3b. if element is a container handle its children, which may be text- or element nodes
47
47
  # 4. finally add the markdown ending tag for this element
48
- def parse_element(element, parent)
48
+ def parse_element(element, parent = nil)
49
49
  name = element.name.to_sym
50
50
  # 1.
51
51
  @output << (" " * @indent) if name.eql?(:li)
@@ -53,28 +53,27 @@ class ReverseMarkdown
53
53
  @output << opening(element, parent)
54
54
 
55
55
  # 3a.
56
- if (element.has_text? and element.children.size < 2)
56
+ if element.children.size == 1 && element.children.first.text?
57
57
  @output << text_node(element, parent)
58
- end
59
-
60
- # 3b.
61
- if element.has_elements?
58
+ else
59
+ # 3b.
62
60
  element.children.each do |child|
63
61
  # increase indent if nested list
64
- @indent += 1 if element.name=~/(ul|ol)/ and parent.eql?(:li)
62
+ @indent += 1 if nested_list?(element, parent)
65
63
 
66
- if child.node_type.eql?(:element)
64
+ if child.element?
67
65
  parse_element(child, element.name.to_sym)
68
66
  else
69
- if parent.eql?(:blockquote)
70
- @output << child.to_s.gsub("\n ", "\n>")
71
- else
72
- @output << child.to_s
73
- end
67
+ @output <<
68
+ if parent.eql?(:blockquote)
69
+ child.inner_text.gsub("\n ", "\n>")
70
+ else
71
+ child.inner_text
72
+ end
74
73
  end
75
74
 
76
75
  # decrease indent if end of nested list
77
- @indent -= 1 if element.name=~/(ul|ol)/ and parent.eql?(:li)
76
+ @indent -= 1 if nested_list?(element, parent)
78
77
  end
79
78
  end
80
79
 
@@ -82,13 +81,19 @@ class ReverseMarkdown
82
81
  @output << ending(element, parent)
83
82
  end
84
83
 
84
+ private
85
+
86
+ def nested_list?(element, parent)
87
+ element.name=~/(ul|ol)/ and parent.eql?(:li)
88
+ end
89
+
85
90
  # Returns opening markdown tag for the element. Its parent matters sometimes!
86
- def opening(type, parent)
91
+ def opening(type, parent_name)
87
92
  case type.name.to_sym
88
93
  when :h1
89
94
  "# "
90
95
  when :li
91
- parent.eql?(:ul) ? " - " : " "+(@li_counter+=1).to_s+". "
96
+ parent_name == :ul ? " - " : " "+(@li_counter+=1).to_s+". "
92
97
  when :ol
93
98
  @li_counter = 0
94
99
  ""
@@ -110,18 +115,16 @@ class ReverseMarkdown
110
115
  "**"
111
116
  when :blockquote
112
117
  # remove leading newline
113
- type.children.first.value = ""
118
+ type.children.first.content = ""
114
119
  "> "
115
120
  when :code
116
- parent.eql?(:pre) ? " " : "`"
121
+ parent_name == :pre ? " " : "`"
117
122
  when :a
118
123
  "["
119
124
  when :img
120
125
  "!["
121
126
  when :hr
122
127
  "----------\n\n"
123
- when :root
124
- ""
125
128
  else
126
129
  @errors << "unknown start tag: "+type.name.to_s
127
130
  ""
@@ -166,8 +169,6 @@ class ReverseMarkdown
166
169
  @links << type.attribute('src').to_s
167
170
  "" + type.attribute('alt').to_s + "][" + @links.size.to_s + "] "
168
171
  "#{type.attribute('alt')}][#{@links.size}] "
169
- when :root
170
- ""
171
172
  else
172
173
  @errors << " unknown end tag: "+type.name.to_s
173
174
  ""
@@ -178,12 +179,16 @@ class ReverseMarkdown
178
179
  # If its a code block to indent of 4 spaces.
179
180
  # For block quotation add a leading '>'
180
181
  def text_node(element, parent)
181
- if element.name.to_sym.eql?(:code) and parent.eql?(:pre)
182
- element.text.gsub("\n","\n ") << "\n"
183
- elsif parent.eql?(:blockquote)
184
- element.text.gsub!("\n ","\n>")
185
- else
186
- element.text
182
+ text_node = element.children.first
183
+ if text_node.text?
184
+ text = text_node.text
185
+ if element.name.to_sym.eql?(:code) and parent.eql?(:pre)
186
+ text.gsub("\n","\n ") << "\n"
187
+ elsif parent.eql?(:blockquote)
188
+ text.gsub!("\n ","\n>")
189
+ else
190
+ text
191
+ end
187
192
  end
188
193
  end
189
194
 
@@ -195,13 +200,6 @@ class ReverseMarkdown
195
200
  end.join
196
201
  end
197
202
 
198
- # Print out all errors, that occured and have been written to @errors.
199
- def print_errors
200
- @errors.each do |error|
201
- puts error
202
- end
203
- end
204
-
205
203
  # Perform a benchmark on a given string n-times.
206
204
  def speed_benchmark(string, n)
207
205
  require 'benchmark'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reverse_markdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-09 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2012-07-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  description:
15
31
  email:
16
32
  executables: []