daimon_markdown 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7dc6824cc4df9719aba51eed6b8fe849b3885d07
4
- data.tar.gz: 8f4b326bf02fefc3d026c11f5a92a5b21c93c3f1
3
+ metadata.gz: 1b919648b289fa4707eb5d83c1543de90eb49add
4
+ data.tar.gz: 15f05ea47e81dfd6ec438426dc7290cabae176e4
5
5
  SHA512:
6
- metadata.gz: dfe1d12e0cac4f1c3ac054acb020665e7508d439475a4f81d37f9cb8ccffac3a6dc24186b7a6f9873b657effd55021ab314bac89381733e4ed501b87cf10aa5a
7
- data.tar.gz: 082116ac11b8cf37ded52adaee2c5f9532c7d3625f32cfc7971f48c2767823df826c63e0fd0f026e634c8fc8ef859fc81491ab74820112433bad61d4cd1ec805
6
+ metadata.gz: cd11bfa96af73ce7d7de20d6678aaa2548fac1bdd72e94a36fa5ad2ba8792421a79af41030784cdc0bfca35f464c0955683c19df6bfce3fcbc8c59246e669352
7
+ data.tar.gz: 250dcf44e7b67d2d3fa57bffa124d85b6fc0eb4ed6e8db485fb1f4ff759da28cac87cc050f25ebdeb44aea55610981b9a55865d2c76b0de16a8987482e332e81
data/README.md CHANGED
@@ -22,12 +22,16 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ For example, in your Rails application:
26
26
 
27
27
  ```ruby
28
- processor = DaimonMarkdown::Processor.new
29
- result = processor.call(input)
30
- puts result[:output].to_s
28
+ module MarkdownHelper
29
+ def render_markdown(markdown_text, context = {})
30
+ processor = DaimonMarkdown::Processor.new(context)
31
+ result = processor.call(markdown_text)
32
+ puts result[:output].to_s.html_safe
33
+ end
34
+ end
31
35
  ```
32
36
 
33
37
  ## How to write plugin
@@ -19,6 +19,20 @@ module DaimonMarkdown
19
19
  node.replace(message)
20
20
  rescue DaimonMarkdown::Plugin::UnknownPluginError => ex
21
21
  node.replace(ex.message)
22
+ rescue DaimonMarkdown::Plugin::Error => ex
23
+ message = <<~MESSAGE
24
+ <pre>Error occured in #{plugin_class}
25
+ #{node} (#{ex.class}: #{ex.message})
26
+ #{ex.backtrace.join("\n")}</pre>
27
+ MESSAGE
28
+ node.parent.replace(message)
29
+ rescue => ex
30
+ message = <<~MESSAGE
31
+ <pre>Unexpected error occured in #{plugin_class}
32
+ #{node} (#{ex.class}: #{ex.message})
33
+ #{ex.backtrace.join("\n")}</pre>
34
+ MESSAGE
35
+ node.parent.replace(message)
22
36
  end
23
37
  end
24
38
  unless result[:plugins].empty?
@@ -6,6 +6,9 @@ module DaimonMarkdown
6
6
  class UnknownPluginError < StandardError
7
7
  end
8
8
 
9
+ class Error < StandardError
10
+ end
11
+
9
12
  class << self
10
13
  def lookup(name)
11
14
  PLUGIN_REGISTRY.fetch(name)
@@ -5,55 +5,134 @@ module DaimonMarkdown
5
5
 
6
6
  def call(limit = nil)
7
7
  toc_html = ""
8
- items = []
8
+ toc_class = context[:toc_class] || "section-nav"
9
9
 
10
- headers = Hash.new(0)
10
+ ul_list = Hash.new {|h, k| h[k] = UnorderedList.new }
11
+ ul_list[1] = UnorderedList.new(html_class: toc_class)
11
12
  previous_level = 1
12
13
  doc.css("h1, h2, h3, h4, h5, h6").each do |header_node|
13
- level = header_node.name.tr("h", "").to_i
14
- next if limit && limit < level
15
- text = header_node.text
16
- id = text.downcase
17
- id.gsub!(/ /, "-")
18
- id.gsub!(/\s/, "")
19
-
20
- if headers[id] > 0
21
- unique_id = "#{id}-#{headers[id]}"
22
- else
23
- unique_id = id
24
- end
25
- headers[id] += 1
26
- header_content = header_node.children.first
27
- # TODO: Arrange indent level
28
- if header_content
29
- diff = level - previous_level
30
- case
31
- when diff > 0
32
- items.concat(["<ul>"] * diff)
33
- when diff < 0
34
- items.concat(["</ul>"] * diff.abs)
14
+ header = Header.new(header_node)
15
+ next if limit && limit < header.level
16
+ next unless header.content?
17
+ header.unique_id = generate_unique_id(header.text)
18
+ if header.level - previous_level > 0
19
+ (previous_level + 1).upto(header.level) do |level|
20
+ ul_list[level - 1] << ul_list[level]
35
21
  end
36
- items << list_item(link_to(unique_id, text))
37
- header_node["id"] = unique_id
38
22
  end
39
- previous_level = level
23
+ ul_list[header.level] << ListItem.new(header: header)
24
+ previous_level = header.level
40
25
  end
41
- toc_class = context[:toc_class] || "section-nav"
42
- toc_header = context[:toc_header] || ""
43
- unless items.empty?
44
- toc_html = %Q(#{toc_header}<ul class="#{toc_class}">\n#{items.join("\n")}\n</ul>)
26
+
27
+ unless ul_list[1].items.empty?
28
+ toc_header = context[:toc_header] || ""
29
+ toc_html = "#{toc_header}#{ul_list[1].to_html}"
45
30
  end
46
31
  node.parent.replace(toc_html)
47
32
  end
48
33
 
49
34
  private
50
35
 
51
- def link_to(href, text)
52
- %Q(<a href="##{href}">#{text}</a>)
36
+ def generate_unique_id(text)
37
+ @headers ||= Hash.new(0)
38
+ id = text.downcase
39
+ id.tr!(" ", "-")
40
+ id.gsub!(/\s/, "")
41
+
42
+ unique_id =
43
+ if @headers[id] > 0
44
+ "#{id}-#{@headers[id]}"
45
+ else
46
+ id
47
+ end
48
+ @headers[id] += 1
49
+ unique_id
50
+ end
51
+
52
+ class Header
53
+ attr_reader :level, :text, :unique_id
54
+
55
+ def initialize(node)
56
+ @node = node
57
+ @level = node.name.tr("h", "").to_i
58
+ @text = node.text
59
+ @unique_id = ""
60
+ end
61
+
62
+ def unique_id=(id)
63
+ @node["id"] = id
64
+ @unique_id = id
65
+ end
66
+
67
+ def content?
68
+ @node.children.first
69
+ end
70
+
71
+ def link
72
+ %Q(<a href="##{unique_id}">#{text}</a>)
73
+ end
74
+
75
+ def to_s
76
+ @node.to_s
77
+ end
53
78
  end
54
79
 
55
- def list_item(content)
56
- %Q(<li>#{content}</li>)
80
+ class EmptyHeader
81
+ def link
82
+ ""
83
+ end
84
+ end
85
+
86
+ class UnorderedList
87
+ attr_reader :items, :level
88
+
89
+ def initialize(html_class: nil, level: 1)
90
+ @html_class = html_class
91
+ @level = level
92
+ @items = []
93
+ end
94
+
95
+ def <<(item)
96
+ case
97
+ when item.is_a?(UnorderedList) && @items.last.is_a?(ListItem)
98
+ @items.last << item
99
+ when item.is_a?(UnorderedList) && @items.last.nil?
100
+ li = ListItem.new
101
+ li << item
102
+ @items << li
103
+ else
104
+ @items << item
105
+ end
106
+ end
107
+
108
+ def to_html
109
+ if @html_class
110
+ %Q(<ul class="#{@html_class}">\n#{@items.map(&:to_html).join("\n")}\n</ul>)
111
+ else
112
+ %Q(<ul>\n#{@items.map(&:to_html).join("\n")}\n</ul>)
113
+ end
114
+ end
115
+ end
116
+
117
+ class ListItem
118
+ attr_reader :items
119
+
120
+ def initialize(header: EmptyHeader.new)
121
+ @header = header
122
+ @items = []
123
+ end
124
+
125
+ def <<(item)
126
+ @items << item
127
+ end
128
+
129
+ def to_html
130
+ if @items.empty?
131
+ %Q(<li>#{@header.link}</li>)
132
+ else
133
+ %Q(<li>#{@header.link}\n#{@items.map(&:to_html).join("\n")}\n</li>)
134
+ end
135
+ end
57
136
  end
58
137
  end
59
138
  end
@@ -1,3 +1,3 @@
1
1
  module DaimonMarkdown
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daimon_markdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - daimon developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-18 00:00:00.000000000 Z
11
+ date: 2017-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: html-pipeline
@@ -185,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
185
  version: '0'
186
186
  requirements: []
187
187
  rubyforge_project:
188
- rubygems_version: 2.6.4
188
+ rubygems_version: 2.6.8
189
189
  signing_key:
190
190
  specification_version: 4
191
191
  summary: Markdown renderer for Daimon