panda-editor 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 148f84007d3e1e31886f6be8297edfd19f5ddc13e29d1ff565d66a7c27261f85
4
- data.tar.gz: 0e2794c6183a16940bdd62c62ff0f63e6b55c0e529adb025e596f93041de565f
3
+ metadata.gz: fbf5326beb171bbb5448b7545bfe87fdef49faac3c82f85c1a64a30cc7aa276d
4
+ data.tar.gz: 05c314fcf2d2b2c5cdfe2d4e2684b392bc2d4cd7231c91870a6f6100a1ca7170
5
5
  SHA512:
6
- metadata.gz: 06cef5d5517ef1211bcfc1b0b5c0c63dba5c8bfd9d189b1074e1174d261d14de5d15c522734cdc69fca71c3ef3cfbbed88fe741de6e739a4c9b49a4a7960219d
7
- data.tar.gz: c169a830348145a9b9f24a62d15333a02fb9b27cc0bdc2356a383ade82010af16369e2279034bae78607ff751844c52a417d872a0146023445bcf7c4d7dc29b8
6
+ metadata.gz: cab18e487c3e4021cebf6ffbd7c98a4c15103ca96a53cbbbd97b3b377a99d83d7c81de246f620359317d166b5716b56d3105be01d7ab1930c96a9f103164ac1b
7
+ data.tar.gz: 1c3ae8993db2fe42ebd8e4c22c664655aa86961757605d897ca5c4c4553b3c0e4427c203d15b23bfae7ce4d83cfc92d6f02d8aa3dc025f3babb3673bc1850de1
data/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.5.0] - 2025-11-04
9
+
10
+ ### Fixed
11
+ - Code quality improvements with Rubocop auto-corrections
12
+ - Fixed 1263 style violations across the codebase
13
+ - Converted double-quoted strings to single quotes where appropriate
14
+ - Improved code consistency and readability
15
+ - Corrected string literal usage throughout
16
+ - Fixed extra spacing and formatting issues
17
+
18
+ ### Changed
19
+ - All tests passing (53 examples, 0 failures)
20
+ - Improved code maintainability
21
+
8
22
  ## [0.4.0] - 2025-10-30
9
23
 
10
24
  ### Added
@@ -9,78 +9,78 @@ module Panda
9
9
  return {} if html.blank?
10
10
 
11
11
  # If it's already in EditorJS format, return as is
12
- return html if html.is_a?(Hash) && (html["blocks"].present? || html[:blocks].present?)
12
+ return html if html.is_a?(Hash) && (html['blocks'].present? || html[:blocks].present?)
13
13
 
14
14
  begin
15
15
  # Parse the HTML content
16
16
  doc = Nokogiri::HTML.fragment(html.to_s)
17
- raise ConversionError, "Failed to parse HTML content" unless doc
17
+ raise ConversionError, 'Failed to parse HTML content' unless doc
18
18
 
19
19
  blocks = []
20
- current_text = ""
20
+ current_text = ''
21
21
 
22
22
  doc.children.each do |node|
23
23
  case node.name
24
- when "h1", "h2", "h3", "h4", "h5", "h6"
24
+ when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
25
25
  # Add any accumulated text as a paragraph before the header
26
26
  if current_text.present?
27
27
  blocks << create_paragraph_block(current_text)
28
- current_text = ""
28
+ current_text = ''
29
29
  end
30
30
 
31
31
  blocks << {
32
- "type" => "header",
33
- "data" => {
34
- "text" => node.text.strip,
35
- "level" => node.name[1].to_i
32
+ 'type' => 'header',
33
+ 'data' => {
34
+ 'text' => node.text.strip,
35
+ 'level' => node.name[1].to_i
36
36
  }
37
37
  }
38
- when "p", "div"
38
+ when 'p', 'div'
39
39
  # Add any accumulated text first
40
40
  if current_text.present?
41
41
  blocks << create_paragraph_block(current_text)
42
- current_text = ""
42
+ current_text = ''
43
43
  end
44
44
 
45
- if node.name == "div"
45
+ if node.name == 'div'
46
46
  # Process div children separately
47
47
  node.children.each do |child|
48
48
  case child.name
49
- when "h1", "h2", "h3", "h4", "h5", "h6"
49
+ when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
50
50
  blocks << {
51
- "type" => "header",
52
- "data" => {
53
- "text" => child.text.strip,
54
- "level" => child.name[1].to_i
51
+ 'type' => 'header',
52
+ 'data' => {
53
+ 'text' => child.text.strip,
54
+ 'level' => child.name[1].to_i
55
55
  }
56
56
  }
57
- when "p"
57
+ when 'p'
58
58
  text = process_inline_elements(child)
59
59
  paragraphs = text.split(%r{<br\s*/?>\s*<br\s*/?>}).map(&:strip)
60
60
  paragraphs.each do |paragraph|
61
61
  blocks << create_paragraph_block(paragraph) if paragraph.present?
62
62
  end
63
- when "ul", "ol"
64
- items = child.css("li").map { |li| process_inline_elements(li) }
63
+ when 'ul', 'ol'
64
+ items = child.css('li').map { |li| process_inline_elements(li) }
65
65
  next if items.empty?
66
66
 
67
67
  blocks << {
68
- "type" => "list",
69
- "data" => {
70
- "style" => (child.name == "ul") ? "unordered" : "ordered",
71
- "items" => items
68
+ 'type' => 'list',
69
+ 'data' => {
70
+ 'style' => child.name == 'ul' ? 'unordered' : 'ordered',
71
+ 'items' => items
72
72
  }
73
73
  }
74
- when "blockquote"
74
+ when 'blockquote'
75
75
  blocks << {
76
- "type" => "quote",
77
- "data" => {
78
- "text" => process_inline_elements(child),
79
- "caption" => "",
80
- "alignment" => "left"
76
+ 'type' => 'quote',
77
+ 'data' => {
78
+ 'text' => process_inline_elements(child),
79
+ 'caption' => '',
80
+ 'alignment' => 'left'
81
81
  }
82
82
  }
83
- when "text"
83
+ when 'text'
84
84
  text = child.text.strip
85
85
  current_text += text if text.present?
86
86
  end
@@ -93,41 +93,41 @@ module Panda
93
93
  blocks << create_paragraph_block(paragraph) if paragraph.present?
94
94
  end
95
95
  end
96
- when "br"
96
+ when 'br'
97
97
  current_text += "\n\n"
98
- when "text"
98
+ when 'text'
99
99
  text = node.text.strip
100
100
  current_text += text if text.present?
101
- when "ul", "ol"
101
+ when 'ul', 'ol'
102
102
  # Add any accumulated text first
103
103
  if current_text.present?
104
104
  blocks << create_paragraph_block(current_text)
105
- current_text = ""
105
+ current_text = ''
106
106
  end
107
107
 
108
- items = node.css("li").map { |li| process_inline_elements(li) }
108
+ items = node.css('li').map { |li| process_inline_elements(li) }
109
109
  next if items.empty?
110
110
 
111
111
  blocks << {
112
- "type" => "list",
113
- "data" => {
114
- "style" => (node.name == "ul") ? "unordered" : "ordered",
115
- "items" => items
112
+ 'type' => 'list',
113
+ 'data' => {
114
+ 'style' => node.name == 'ul' ? 'unordered' : 'ordered',
115
+ 'items' => items
116
116
  }
117
117
  }
118
- when "blockquote"
118
+ when 'blockquote'
119
119
  # Add any accumulated text first
120
120
  if current_text.present?
121
121
  blocks << create_paragraph_block(current_text)
122
- current_text = ""
122
+ current_text = ''
123
123
  end
124
124
 
125
125
  blocks << {
126
- "type" => "quote",
127
- "data" => {
128
- "text" => process_inline_elements(node),
129
- "caption" => "",
130
- "alignment" => "left"
126
+ 'type' => 'quote',
127
+ 'data' => {
128
+ 'text' => process_inline_elements(node),
129
+ 'caption' => '',
130
+ 'alignment' => 'left'
131
131
  }
132
132
  }
133
133
  end
@@ -138,11 +138,11 @@ module Panda
138
138
 
139
139
  # Return the complete EditorJS structure
140
140
  {
141
- "time" => Time.current.to_i * 1000,
142
- "blocks" => blocks,
143
- "version" => "2.28.2"
141
+ 'time' => Time.current.to_i * 1000,
142
+ 'blocks' => blocks,
143
+ 'version' => '2.28.2'
144
144
  }
145
- rescue => e
145
+ rescue StandardError => e
146
146
  Rails.logger.error "HTML to EditorJS conversion failed: #{e.message}"
147
147
  Rails.logger.error e.backtrace.join("\n")
148
148
  raise ConversionError, "Failed to convert HTML to EditorJS format: #{e.message}"
@@ -151,41 +151,41 @@ module Panda
151
151
 
152
152
  def self.create_paragraph_block(text)
153
153
  {
154
- "type" => "paragraph",
155
- "data" => {
156
- "text" => text.strip
154
+ 'type' => 'paragraph',
155
+ 'data' => {
156
+ 'text' => text.strip
157
157
  }
158
158
  }
159
159
  end
160
160
 
161
161
  def self.process_inline_elements(node)
162
- result = ""
162
+ result = ''
163
163
  node.children.each do |child|
164
164
  case child.name
165
- when "br"
166
- result += "<br>"
167
- when "text"
165
+ when 'br'
166
+ result += '<br>'
167
+ when 'text'
168
168
  result += child.text
169
- when "strong", "b"
169
+ when 'strong', 'b'
170
170
  result += "<b>#{child.text}</b>"
171
- when "em", "i"
171
+ when 'em', 'i'
172
172
  result += "<i>#{child.text}</i>"
173
- when "a"
174
- href = child["href"]
173
+ when 'a'
174
+ href = child['href']
175
175
  text = child.text.strip
176
176
  # Handle email links specially
177
- if href&.start_with?("mailto:")
178
- email = href.sub("mailto:", "")
177
+ if href&.start_with?('mailto:')
178
+ email = href.sub('mailto:', '')
179
179
  result += "<a href=\"mailto:#{email}\">#{text}</a>"
180
180
  else
181
181
  result += "<a href=\"#{href}\">#{text}</a>"
182
182
  end
183
183
  else
184
184
  result += if child.text?
185
- child.text
186
- else
187
- child.to_html
188
- end
185
+ child.text
186
+ else
187
+ child.to_html
188
+ end
189
189
  end
190
190
  end
191
191
  result.strip
data/config/importmap.rb CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  # Pin npm packages by running ./bin/importmap
4
4
 
5
- pin_all_from "app/javascript/panda/editor", under: "panda/editor"
5
+ pin_all_from 'app/javascript/panda/editor', under: 'panda/editor'
6
6
 
7
7
  # EditorJS Core and plugins (from CDN)
8
- pin "@editorjs/editorjs", to: "https://cdn.jsdelivr.net/npm/@editorjs/editorjs@2.28.2/+esm"
9
- pin "@editorjs/paragraph", to: "https://cdn.jsdelivr.net/npm/@editorjs/paragraph@2.11.3/+esm"
10
- pin "@editorjs/header", to: "https://cdn.jsdelivr.net/npm/@editorjs/header@2.8.1/+esm"
11
- pin "@editorjs/nested-list", to: "https://cdn.jsdelivr.net/npm/@editorjs/nested-list@1.4.2/+esm"
12
- pin "@editorjs/quote", to: "https://cdn.jsdelivr.net/npm/@editorjs/quote@2.6.0/+esm"
13
- pin "@editorjs/simple-image", to: "https://cdn.jsdelivr.net/npm/@editorjs/simple-image@1.6.0/+esm"
14
- pin "@editorjs/table", to: "https://cdn.jsdelivr.net/npm/@editorjs/table@2.3.0/+esm"
15
- pin "@editorjs/embed", to: "https://cdn.jsdelivr.net/npm/@editorjs/embed@2.7.0/+esm"
8
+ pin '@editorjs/editorjs', to: 'https://cdn.jsdelivr.net/npm/@editorjs/editorjs@2.28.2/+esm'
9
+ pin '@editorjs/paragraph', to: 'https://cdn.jsdelivr.net/npm/@editorjs/paragraph@2.11.3/+esm'
10
+ pin '@editorjs/header', to: 'https://cdn.jsdelivr.net/npm/@editorjs/header@2.8.1/+esm'
11
+ pin '@editorjs/nested-list', to: 'https://cdn.jsdelivr.net/npm/@editorjs/nested-list@1.4.2/+esm'
12
+ pin '@editorjs/quote', to: 'https://cdn.jsdelivr.net/npm/@editorjs/quote@2.6.0/+esm'
13
+ pin '@editorjs/simple-image', to: 'https://cdn.jsdelivr.net/npm/@editorjs/simple-image@1.6.0/+esm'
14
+ pin '@editorjs/table', to: 'https://cdn.jsdelivr.net/npm/@editorjs/table@2.3.0/+esm'
15
+ pin '@editorjs/embed', to: 'https://cdn.jsdelivr.net/npm/@editorjs/embed@2.7.0/+esm'
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "net/http"
4
- require "json"
3
+ require 'net/http'
4
+ require 'json'
5
5
 
6
6
  module Panda
7
7
  module Editor
8
8
  class AssetLoader
9
- GITHUB_RELEASES_URL = "https://api.github.com/repos/tastybamboo/panda-editor/releases/latest"
10
- ASSET_CACHE_DIR = Rails.root.join("tmp", "panda_editor_assets")
9
+ GITHUB_RELEASES_URL = 'https://api.github.com/repos/tastybamboo/panda-editor/releases/latest'
10
+ ASSET_CACHE_DIR = Rails.root.join('tmp', 'panda_editor_assets')
11
11
 
12
12
  class << self
13
13
  def load_assets
@@ -22,7 +22,7 @@ module Panda
22
22
  if use_compiled_assets?
23
23
  compiled_javascript_url
24
24
  else
25
- "/assets/panda/editor/application.js"
25
+ '/assets/panda/editor/application.js'
26
26
  end
27
27
  end
28
28
 
@@ -30,7 +30,7 @@ module Panda
30
30
  if use_compiled_assets?
31
31
  compiled_stylesheet_url
32
32
  else
33
- "/assets/panda/editor/application.css"
33
+ '/assets/panda/editor/application.css'
34
34
  end
35
35
  end
36
36
 
@@ -39,7 +39,7 @@ module Panda
39
39
  def use_compiled_assets?
40
40
  Rails.env.production? ||
41
41
  Rails.env.test? ||
42
- ENV["PANDA_EDITOR_USE_COMPILED_ASSETS"] == "true"
42
+ ENV['PANDA_EDITOR_USE_COMPILED_ASSETS'] == 'true'
43
43
  end
44
44
 
45
45
  def load_compiled_assets
@@ -52,23 +52,23 @@ module Panda
52
52
 
53
53
  def load_development_assets
54
54
  {
55
- javascript: "/assets/panda/editor/application.js",
56
- stylesheet: "/assets/panda/editor/application.css"
55
+ javascript: '/assets/panda/editor/application.js',
56
+ stylesheet: '/assets/panda/editor/application.css'
57
57
  }
58
58
  end
59
59
 
60
60
  def compiled_javascript_url
61
- asset_path = find_latest_asset("js")
61
+ asset_path = find_latest_asset('js')
62
62
  asset_path ? "/panda-editor-assets/#{File.basename(asset_path)}" : nil
63
63
  end
64
64
 
65
65
  def compiled_stylesheet_url
66
- asset_path = find_latest_asset("css")
66
+ asset_path = find_latest_asset('css')
67
67
  asset_path ? "/panda-editor-assets/#{File.basename(asset_path)}" : nil
68
68
  end
69
69
 
70
70
  def find_latest_asset(extension)
71
- pattern = Rails.root.join("public", "panda-editor-assets", "panda-editor-*.#{extension}")
71
+ pattern = Rails.root.join('public', 'panda-editor-assets', "panda-editor-*.#{extension}")
72
72
  Dir.glob(pattern).max_by { |f| File.mtime(f) }
73
73
  end
74
74
 
@@ -79,18 +79,18 @@ module Panda
79
79
  end
80
80
 
81
81
  def assets_exist?
82
- js_exists = Dir.glob(Rails.root.join("public", "panda-editor-assets", "panda-editor-*.js")).any?
83
- css_exists = Dir.glob(Rails.root.join("public", "panda-editor-assets", "panda-editor-*.css")).any?
82
+ js_exists = Dir.glob(Rails.root.join('public', 'panda-editor-assets', 'panda-editor-*.js')).any?
83
+ css_exists = Dir.glob(Rails.root.join('public', 'panda-editor-assets', 'panda-editor-*.css')).any?
84
84
  js_exists && css_exists
85
85
  end
86
86
 
87
87
  def download_assets_from_github
88
- Rails.logger.info "[Panda Editor] Downloading assets from GitHub releases..."
88
+ Rails.logger.info '[Panda Editor] Downloading assets from GitHub releases...'
89
89
 
90
90
  begin
91
91
  release_data = fetch_latest_release
92
- download_release_assets(release_data["assets"])
93
- rescue => e
92
+ download_release_assets(release_data['assets'])
93
+ rescue StandardError => e
94
94
  Rails.logger.error "[Panda Editor] Failed to download assets: #{e.message}"
95
95
  use_fallback_assets
96
96
  end
@@ -100,32 +100,30 @@ module Panda
100
100
  uri = URI(GITHUB_RELEASES_URL)
101
101
  response = Net::HTTP.get_response(uri)
102
102
 
103
- if response.code == "200"
104
- JSON.parse(response.body)
105
- else
106
- raise "GitHub API returned #{response.code}"
107
- end
103
+ raise "GitHub API returned #{response.code}" unless response.code == '200'
104
+
105
+ JSON.parse(response.body)
108
106
  end
109
107
 
110
108
  def download_release_assets(assets)
111
109
  assets.each do |asset|
112
- next unless asset["name"].match?(/panda-editor.*\.(js|css)$/)
110
+ next unless asset['name'].match?(/panda-editor.*\.(js|css)$/)
113
111
 
114
112
  download_asset(asset)
115
113
  end
116
114
  end
117
115
 
118
116
  def download_asset(asset)
119
- uri = URI(asset["browser_download_url"])
117
+ uri = URI(asset['browser_download_url'])
120
118
  response = Net::HTTP.get_response(uri)
121
119
 
122
- if response.code == "200"
123
- save_asset(asset["name"], response.body)
124
- end
120
+ return unless response.code == '200'
121
+
122
+ save_asset(asset['name'], response.body)
125
123
  end
126
124
 
127
125
  def save_asset(filename, content)
128
- dir = Rails.root.join("public", "panda-editor-assets")
126
+ dir = Rails.root.join('public', 'panda-editor-assets')
129
127
  FileUtils.mkdir_p(dir)
130
128
 
131
129
  File.write(dir.join(filename), content)
@@ -133,17 +131,17 @@ module Panda
133
131
  end
134
132
 
135
133
  def use_fallback_assets
136
- Rails.logger.warn "[Panda Editor] Using fallback embedded assets"
134
+ Rails.logger.warn '[Panda Editor] Using fallback embedded assets'
137
135
  # Copy embedded assets from gem to public directory
138
136
  copy_embedded_assets
139
137
  end
140
138
 
141
139
  def copy_embedded_assets
142
- source_dir = Panda::Editor::Engine.root.join("public", "panda-editor-assets")
143
- dest_dir = Rails.root.join("public", "panda-editor-assets")
140
+ source_dir = Panda::Editor::Engine.root.join('public', 'panda-editor-assets')
141
+ dest_dir = Rails.root.join('public', 'panda-editor-assets')
144
142
 
145
143
  FileUtils.mkdir_p(dest_dir)
146
- FileUtils.cp_r(Dir.glob(source_dir.join("*")), dest_dir)
144
+ FileUtils.cp_r(Dir.glob(source_dir.join('*')), dest_dir)
147
145
  end
148
146
  end
149
147
  end
@@ -5,13 +5,13 @@ module Panda
5
5
  module Blocks
6
6
  class Alert < Base
7
7
  def render
8
- message = sanitize(data["message"])
9
- type = data["type"] || "primary"
8
+ message = sanitize(data['message'])
9
+ type = data['type'] || 'primary'
10
10
 
11
11
  html_safe(
12
12
  "<div class=\"#{alert_classes(type)} p-4 mb-4 rounded-lg\">" \
13
13
  "#{message}" \
14
- "</div>"
14
+ '</div>'
15
15
  )
16
16
  end
17
17
 
@@ -19,13 +19,13 @@ module Panda
19
19
 
20
20
  def alert_classes(type)
21
21
  case type
22
- when "primary" then "bg-blue-100 text-blue-800"
23
- when "secondary" then "bg-gray-100 text-gray-800"
24
- when "success" then "bg-green-100 text-green-800"
25
- when "danger" then "bg-red-100 text-red-800"
26
- when "warning" then "bg-yellow-100 text-yellow-800"
27
- when "info" then "bg-indigo-100 text-indigo-800"
28
- else "bg-blue-100 text-blue-800"
22
+ when 'primary' then 'bg-blue-100 text-blue-800'
23
+ when 'secondary' then 'bg-gray-100 text-gray-800'
24
+ when 'success' then 'bg-green-100 text-green-800'
25
+ when 'danger' then 'bg-red-100 text-red-800'
26
+ when 'warning' then 'bg-yellow-100 text-yellow-800'
27
+ when 'info' then 'bg-indigo-100 text-indigo-800'
28
+ else 'bg-blue-100 text-blue-800'
29
29
  end
30
30
  end
31
31
  end
@@ -15,7 +15,7 @@ module Panda
15
15
  end
16
16
 
17
17
  def render
18
- ""
18
+ ''
19
19
  end
20
20
 
21
21
  protected
@@ -5,8 +5,8 @@ module Panda
5
5
  module Blocks
6
6
  class Header < Base
7
7
  def render
8
- content = sanitize(data["text"])
9
- level = data["level"] || 2
8
+ content = sanitize(data['text'])
9
+ level = data['level'] || 2
10
10
  html_safe("<h#{level}>#{content}</h#{level}>")
11
11
  end
12
12
  end
@@ -5,19 +5,19 @@ module Panda
5
5
  module Blocks
6
6
  class Image < Base
7
7
  def render
8
- url = data["url"]
9
- caption = sanitize(data["caption"])
10
- with_border = data["withBorder"]
11
- with_background = data["withBackground"]
12
- stretched = data["stretched"]
8
+ url = data['url']
9
+ caption = sanitize(data['caption'])
10
+ with_border = data['withBorder']
11
+ with_background = data['withBackground']
12
+ stretched = data['stretched']
13
13
 
14
- css_classes = ["prose"]
15
- css_classes << "border" if with_border
16
- css_classes << "bg-gray-100" if with_background
17
- css_classes << "w-full" if stretched
14
+ css_classes = ['prose']
15
+ css_classes << 'border' if with_border
16
+ css_classes << 'bg-gray-100' if with_background
17
+ css_classes << 'w-full' if stretched
18
18
 
19
19
  html_safe(<<~HTML)
20
- <figure class="#{css_classes.join(" ")}">
20
+ <figure class="#{css_classes.join(' ')}">
21
21
  <img src="#{url}" alt="#{caption}" />
22
22
  #{caption_element(caption)}
23
23
  </figure>
@@ -27,7 +27,7 @@ module Panda
27
27
  private
28
28
 
29
29
  def caption_element(caption)
30
- return "" if caption.blank?
30
+ return '' if caption.blank?
31
31
 
32
32
  "<figcaption>#{caption}</figcaption>"
33
33
  end
@@ -5,10 +5,10 @@ module Panda
5
5
  module Blocks
6
6
  class List < Base
7
7
  def render
8
- list_type = (data["style"] == "ordered") ? "ol" : "ul"
8
+ list_type = data['style'] == 'ordered' ? 'ol' : 'ul'
9
9
  html_safe(
10
10
  "<#{list_type}>" \
11
- "#{render_items(data["items"])}" \
11
+ "#{render_items(data['items'])}" \
12
12
  "</#{list_type}>"
13
13
  )
14
14
  end
@@ -17,14 +17,14 @@ module Panda
17
17
 
18
18
  def render_items(items)
19
19
  items.map do |item|
20
- content = item.is_a?(Hash) ? item["content"] : item
21
- nested = (item.is_a?(Hash) && item["items"].present?) ? render_nested(item["items"]) : ""
20
+ content = item.is_a?(Hash) ? item['content'] : item
21
+ nested = item.is_a?(Hash) && item['items'].present? ? render_nested(item['items']) : ''
22
22
  "<li>#{sanitize(content)}#{nested}</li>"
23
23
  end.join
24
24
  end
25
25
 
26
26
  def render_nested(items)
27
- self.class.new({"items" => items, "style" => data["style"]}).render
27
+ self.class.new({ 'items' => items, 'style' => data['style'] }).render
28
28
  end
29
29
  end
30
30
  end