prosereflect 0.1.1 → 0.2.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +4 -0
  3. data/.github/workflows/release.yml +5 -0
  4. data/.rubocop.yml +19 -1
  5. data/.rubocop_todo.yml +141 -191
  6. data/CLAUDE.md +78 -0
  7. data/Gemfile +8 -4
  8. data/Rakefile +3 -3
  9. data/lib/prosereflect/attribute/base.rb +4 -6
  10. data/lib/prosereflect/attribute/bold.rb +2 -4
  11. data/lib/prosereflect/attribute/href.rb +1 -3
  12. data/lib/prosereflect/attribute/id.rb +7 -7
  13. data/lib/prosereflect/attribute.rb +4 -7
  14. data/lib/prosereflect/blockquote.rb +10 -11
  15. data/lib/prosereflect/bullet_list.rb +16 -15
  16. data/lib/prosereflect/code_block.rb +26 -26
  17. data/lib/prosereflect/code_block_wrapper.rb +12 -13
  18. data/lib/prosereflect/document.rb +14 -22
  19. data/lib/prosereflect/hard_break.rb +6 -6
  20. data/lib/prosereflect/heading.rb +14 -15
  21. data/lib/prosereflect/horizontal_rule.rb +14 -14
  22. data/lib/prosereflect/image.rb +23 -23
  23. data/lib/prosereflect/input/html.rb +83 -104
  24. data/lib/prosereflect/input.rb +7 -0
  25. data/lib/prosereflect/list_item.rb +11 -12
  26. data/lib/prosereflect/mark/base.rb +9 -11
  27. data/lib/prosereflect/mark/bold.rb +1 -3
  28. data/lib/prosereflect/mark/code.rb +1 -3
  29. data/lib/prosereflect/mark/italic.rb +1 -3
  30. data/lib/prosereflect/mark/link.rb +1 -3
  31. data/lib/prosereflect/mark/strike.rb +1 -3
  32. data/lib/prosereflect/mark/subscript.rb +1 -3
  33. data/lib/prosereflect/mark/superscript.rb +1 -3
  34. data/lib/prosereflect/mark/underline.rb +1 -3
  35. data/lib/prosereflect/mark.rb +9 -5
  36. data/lib/prosereflect/node.rb +31 -31
  37. data/lib/prosereflect/ordered_list.rb +15 -14
  38. data/lib/prosereflect/output/html.rb +52 -50
  39. data/lib/prosereflect/output.rb +7 -0
  40. data/lib/prosereflect/paragraph.rb +11 -13
  41. data/lib/prosereflect/parser.rb +47 -66
  42. data/lib/prosereflect/table.rb +12 -13
  43. data/lib/prosereflect/table_cell.rb +13 -13
  44. data/lib/prosereflect/table_header.rb +17 -17
  45. data/lib/prosereflect/table_row.rb +12 -12
  46. data/lib/prosereflect/text.rb +11 -11
  47. data/lib/prosereflect/user.rb +15 -15
  48. data/lib/prosereflect/version.rb +1 -1
  49. data/lib/prosereflect.rb +27 -17
  50. data/prosereflect.gemspec +17 -16
  51. data/spec/prosereflect/document_spec.rb +332 -330
  52. data/spec/prosereflect/hard_break_spec.rb +125 -125
  53. data/spec/prosereflect/input/html_spec.rb +522 -522
  54. data/spec/prosereflect/node_spec.rb +183 -182
  55. data/spec/prosereflect/output/html_spec.rb +105 -105
  56. data/spec/prosereflect/paragraph_spec.rb +275 -274
  57. data/spec/prosereflect/parser_spec.rb +185 -180
  58. data/spec/prosereflect/table_cell_spec.rb +183 -183
  59. data/spec/prosereflect/table_row_spec.rb +149 -149
  60. data/spec/prosereflect/table_spec.rb +320 -318
  61. data/spec/prosereflect/text_spec.rb +133 -132
  62. data/spec/prosereflect/user_spec.rb +31 -28
  63. data/spec/prosereflect_spec.rb +28 -26
  64. data/spec/spec_helper.rb +6 -6
  65. data/spec/support/matchers.rb +6 -6
  66. data/spec/support/shared_examples.rb +49 -49
  67. metadata +8 -5
  68. data/spec/prosereflect/version_spec.rb +0 -11
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
-
5
3
  # {
6
4
  # type: "italic"
7
5
  # }
@@ -9,7 +7,7 @@ require_relative 'base'
9
7
  module Prosereflect
10
8
  module Mark
11
9
  class Italic < Base
12
- PM_TYPE = 'italic'
10
+ PM_TYPE = "italic"
13
11
  end
14
12
  end
15
13
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
-
5
3
  # {
6
4
  # type: "link",
7
5
  # attrs: {
@@ -12,7 +10,7 @@ require_relative 'base'
12
10
  module Prosereflect
13
11
  module Mark
14
12
  class Link < Base
15
- PM_TYPE = 'link'
13
+ PM_TYPE = "link"
16
14
  end
17
15
  end
18
16
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
-
5
3
  # {
6
4
  # type: "strike"
7
5
  # }
@@ -9,7 +7,7 @@ require_relative 'base'
9
7
  module Prosereflect
10
8
  module Mark
11
9
  class Strike < Base
12
- PM_TYPE = 'strike'
10
+ PM_TYPE = "strike"
13
11
  end
14
12
  end
15
13
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
-
5
3
  # {
6
4
  # type: "subscript"
7
5
  # }
@@ -9,7 +7,7 @@ require_relative 'base'
9
7
  module Prosereflect
10
8
  module Mark
11
9
  class Subscript < Base
12
- PM_TYPE = 'subscript'
10
+ PM_TYPE = "subscript"
13
11
  end
14
12
  end
15
13
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
-
5
3
  # {
6
4
  # type: "superscript"
7
5
  # }
@@ -9,7 +7,7 @@ require_relative 'base'
9
7
  module Prosereflect
10
8
  module Mark
11
9
  class Superscript < Base
12
- PM_TYPE = 'superscript'
10
+ PM_TYPE = "superscript"
13
11
  end
14
12
  end
15
13
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
-
5
3
  # {
6
4
  # type: "underline"
7
5
  # }
@@ -9,7 +7,7 @@ require_relative 'base'
9
7
  module Prosereflect
10
8
  module Mark
11
9
  class Underline < Base
12
- PM_TYPE = 'underline'
10
+ PM_TYPE = "underline"
13
11
  end
14
12
  end
15
13
  end
@@ -2,10 +2,14 @@
2
2
 
3
3
  module Prosereflect
4
4
  module Mark
5
+ autoload :Base, "#{__dir__}/mark/base"
6
+ autoload :Bold, "#{__dir__}/mark/bold"
7
+ autoload :Italic, "#{__dir__}/mark/italic"
8
+ autoload :Code, "#{__dir__}/mark/code"
9
+ autoload :Link, "#{__dir__}/mark/link"
10
+ autoload :Strike, "#{__dir__}/mark/strike"
11
+ autoload :Subscript, "#{__dir__}/mark/subscript"
12
+ autoload :Superscript, "#{__dir__}/mark/superscript"
13
+ autoload :Underline, "#{__dir__}/mark/underline"
5
14
  end
6
15
  end
7
-
8
- require_relative 'mark/bold'
9
- require_relative 'mark/italic'
10
- require_relative 'mark/code'
11
- require_relative 'mark/link'
@@ -1,12 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'lutaml/model'
4
- require_relative 'attribute'
5
- require_relative 'mark'
6
-
7
3
  module Prosereflect
8
4
  class Node < Lutaml::Model::Serializable
9
- PM_TYPE = 'node'
5
+ PM_TYPE = "node"
10
6
 
11
7
  attribute :type, :string
12
8
  attribute :attrs, :hash
@@ -14,10 +10,10 @@ module Prosereflect
14
10
  attribute :content, Node, polymorphic: true, collection: true
15
11
 
16
12
  key_value do
17
- map 'type', to: :type, render_default: true
18
- map 'attrs', to: :attrs
19
- map 'marks', to: :marks
20
- map 'content', to: :content
13
+ map "type", to: :type, render_default: true
14
+ map "attrs", to: :attrs
15
+ map "marks", to: :marks
16
+ map "content", to: :content
21
17
  end
22
18
 
23
19
  def initialize(data = nil, attrs = nil)
@@ -25,18 +21,18 @@ module Prosereflect
25
21
  super(type: data, attrs: attrs, content: [])
26
22
  elsif data.is_a?(Hash)
27
23
  # Handle marks in a special way to preserve expected behavior in tests
28
- if data[:marks] || data['marks']
29
- marks_data = data[:marks] || data['marks']
24
+ if data[:marks] || data["marks"]
25
+ marks_data = data[:marks] || data["marks"]
30
26
  data = data.dup
31
- data.delete('marks')
27
+ data.delete("marks")
32
28
  data.delete(:marks)
33
29
  super(data)
34
30
  self.marks = marks_data
35
31
  else
36
32
  # Handle attrs properly
37
- if data[:attrs] || data['attrs']
33
+ if data[:attrs] || data["attrs"]
38
34
  data = data.dup
39
- data[:attrs] = process_attrs_data(data[:attrs] || data['attrs'])
35
+ data[:attrs] = process_attrs_data(data[:attrs] || data["attrs"])
40
36
  end
41
37
  super(data)
42
38
  end
@@ -56,33 +52,35 @@ module Prosereflect
56
52
  def self.create(type = nil, attrs = nil)
57
53
  new(type || self::PM_TYPE, attrs)
58
54
  rescue NameError
59
- new(type || 'node', attrs)
55
+ new(type || "node", attrs)
60
56
  end
61
57
 
62
58
  # Convert to hash for serialization
63
59
  def to_h
64
- result = { 'type' => type }
60
+ result = { "type" => type }
65
61
 
66
62
  if attrs && !attrs.empty?
67
63
  if attrs.is_a?(Hash)
68
- result['attrs'] = process_node_attributes(attrs, type)
69
- elsif attrs.is_a?(Array) && attrs.all? { |attr| attr.respond_to?(:to_h) }
64
+ result["attrs"] = process_node_attributes(attrs, type)
65
+ elsif attrs.is_a?(Array) && attrs.all? do |attr|
66
+ attr.respond_to?(:to_h)
67
+ end
70
68
  # Convert array of attribute objects to a hash
71
69
  attrs_array = attrs.map do |attr|
72
70
  attr.is_a?(Prosereflect::Attribute::Base) ? attr.to_h : attr
73
71
  end
74
- result['attrs'] = attrs_array unless attrs_array.empty?
72
+ result["attrs"] = attrs_array unless attrs_array.empty?
75
73
  end
76
74
  end
77
75
 
78
76
  if marks && !marks.empty?
79
- result['marks'] = marks.map do |mark|
77
+ result["marks"] = marks.map do |mark|
80
78
  if mark.is_a?(Hash)
81
79
  mark
82
80
  elsif mark.respond_to?(:to_h)
83
81
  mark.to_h
84
82
  elsif mark.respond_to?(:type)
85
- { 'type' => mark.type.to_s }
83
+ { "type" => mark.type.to_s }
86
84
  else
87
85
  raise ArgumentError, "Invalid mark type: #{mark.class}"
88
86
  end
@@ -90,8 +88,10 @@ module Prosereflect
90
88
  end
91
89
 
92
90
  if content && !content.empty?
93
- result['content'] = if content.is_a?(Array)
94
- content.map { |item| item.respond_to?(:to_h) ? item.to_h : item }
91
+ result["content"] = if content.is_a?(Array)
92
+ content.map do |item|
93
+ item.respond_to?(:to_h) ? item.to_h : item
94
+ end
95
95
  else
96
96
  [content]
97
97
  end
@@ -112,7 +112,7 @@ module Prosereflect
112
112
  elsif mark.respond_to?(:to_h)
113
113
  mark.to_h
114
114
  elsif mark.respond_to?(:type)
115
- { 'type' => mark.type.to_s }
115
+ { "type" => mark.type.to_s }
116
116
  else
117
117
  raise ArgumentError, "Invalid mark type: #{mark.class}"
118
118
  end
@@ -131,8 +131,8 @@ module Prosereflect
131
131
  elsif value.is_a?(Array)
132
132
  @marks = value.map do |v|
133
133
  if v.is_a?(Hash)
134
- type = v['type'] || v[:type]
135
- attrs = v['attrs'] || v[:attrs]
134
+ type = v["type"] || v[:type]
135
+ attrs = v["attrs"] || v[:attrs]
136
136
  begin
137
137
  mark_class = Prosereflect::Mark.const_get(type.to_s.capitalize)
138
138
  mark_class.new(attrs: attrs)
@@ -197,11 +197,11 @@ module Prosereflect
197
197
  def find_children(node_type)
198
198
  return [] unless content
199
199
 
200
- content.select { |child| child.is_a?(node_type) }
200
+ content.grep(node_type)
201
201
  end
202
202
 
203
203
  def text_content
204
- return '' unless content
204
+ return "" unless content
205
205
 
206
206
  content.map(&:text_content).join
207
207
  end
@@ -214,9 +214,9 @@ module Prosereflect
214
214
  private
215
215
 
216
216
  def process_node_attributes(attrs, node_type)
217
- if attrs['attrs'].is_a?(Hash)
218
- attrs['attrs']
219
- elsif node_type == 'bullet_list' && attrs['bullet_style'].nil?
217
+ if attrs["attrs"].is_a?(Hash)
218
+ attrs["attrs"]
219
+ elsif node_type == "bullet_list" && attrs["bullet_style"].nil?
220
220
  nil
221
221
  else
222
222
  attrs
@@ -1,21 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'node'
4
- require_relative 'list_item'
5
-
6
3
  module Prosereflect
7
4
  # OrderedList class represents a numbered list in ProseMirror.
8
5
  class OrderedList < Node
9
- PM_TYPE = 'ordered_list'
6
+ PM_TYPE = "ordered_list"
10
7
 
11
- attribute :type, :string, default: -> { send('const_get', 'PM_TYPE') }
8
+ attribute :type, :string, default: -> {
9
+ self.class.send(:const_get, "PM_TYPE")
10
+ }
12
11
  attribute :start, :integer
13
12
  attribute :attrs, :hash
14
13
 
15
14
  key_value do
16
- map 'type', to: :type, render_default: true
17
- map 'attrs', to: :attrs
18
- map 'content', to: :content
15
+ map "type", to: :type, render_default: true
16
+ map "attrs", to: :attrs
17
+ map "content", to: :content
19
18
  end
20
19
 
21
20
  def initialize(attributes = {})
@@ -30,11 +29,11 @@ module Prosereflect
30
29
  def start=(value)
31
30
  @start = value
32
31
  self.attrs ||= {}
33
- attrs['start'] = value
32
+ attrs["start"] = value
34
33
  end
35
34
 
36
35
  def start
37
- @start || attrs&.[]('start') || 1
36
+ @start || attrs&.[]("start") || 1
38
37
  end
39
38
 
40
39
  def add_item(text)
@@ -67,19 +66,21 @@ module Prosereflect
67
66
  # Update the order (1 for numerical, 'a' for alphabetical, etc.)
68
67
  def order=(order_value)
69
68
  self.attrs ||= {}
70
- attrs['order'] = order_value
69
+ attrs["order"] = order_value
71
70
  end
72
71
 
73
72
  # Get the order value
74
73
  def order
75
- attrs&.[]('order') || 1
74
+ attrs&.[]("order") || 1
76
75
  end
77
76
 
78
77
  # Get text content with proper formatting
79
78
  def text_content
80
- return '' unless content
79
+ return "" unless content
81
80
 
82
- content.map { |item| item.respond_to?(:text_content) ? item.text_content : '' }.join("\n")
81
+ content.map do |item|
82
+ item.respond_to?(:text_content) ? item.text_content : ""
83
+ end.join("\n")
83
84
  end
84
85
  end
85
86
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'nokogiri'
4
- require_relative '../document'
3
+ require "nokogiri"
5
4
 
6
5
  module Prosereflect
7
6
  module Output
@@ -16,7 +15,7 @@ module Prosereflect
16
15
  end
17
16
 
18
17
  doc = Nokogiri::HTML(builder.to_html)
19
- html = doc.at_css('div').children.to_html
18
+ html = doc.at_css("div").children.to_html
20
19
 
21
20
  code_blocks = {}
22
21
  html.scan(%r{<code[^>]*>(.*?)</code>}m).each_with_index do |match, i|
@@ -27,7 +26,7 @@ module Prosereflect
27
26
  end
28
27
 
29
28
  # Remove newlines and spaces
30
- html = html.gsub(/\n\s*/, '')
29
+ html = html.gsub(/\n\s*/, "")
31
30
 
32
31
  code_blocks.each do |placeholder, content|
33
32
  html.sub!(placeholder, content)
@@ -43,41 +42,41 @@ module Prosereflect
43
42
  return unless node
44
43
 
45
44
  case node.type
46
- when 'doc'
45
+ when "doc"
47
46
  process_document(node, builder)
48
- when 'paragraph'
47
+ when "paragraph"
49
48
  process_paragraph(node, builder)
50
- when 'heading'
49
+ when "heading"
51
50
  process_heading(node, builder)
52
- when 'text'
51
+ when "text"
53
52
  process_text(node, builder)
54
- when 'table'
53
+ when "table"
55
54
  process_table(node, builder)
56
- when 'table_row'
55
+ when "table_row"
57
56
  process_table_row(node, builder)
58
- when 'table_cell'
57
+ when "table_cell"
59
58
  process_table_cell(node, builder)
60
- when 'table_header'
59
+ when "table_header"
61
60
  process_table_header(node, builder)
62
- when 'hard_break'
61
+ when "hard_break"
63
62
  builder.br
64
- when 'image'
63
+ when "image"
65
64
  process_image(node, builder)
66
- when 'user'
65
+ when "user"
67
66
  process_user(node, builder)
68
- when 'bullet_list'
67
+ when "bullet_list"
69
68
  process_bullet_list(node, builder)
70
- when 'ordered_list'
69
+ when "ordered_list"
71
70
  process_ordered_list(node, builder)
72
- when 'list_item'
71
+ when "list_item"
73
72
  process_list_item(node, builder)
74
- when 'blockquote'
73
+ when "blockquote"
75
74
  process_blockquote(node, builder)
76
- when 'horizontal_rule'
75
+ when "horizontal_rule"
77
76
  process_horizontal_rule(node, builder)
78
- when 'code_block_wrapper'
77
+ when "code_block_wrapper"
79
78
  process_code_block_wrapper(node, builder)
80
- when 'code_block'
79
+ when "code_block"
81
80
  process_code_block(node, builder)
82
81
  else
83
82
  # Default handling for unknown nodes - treat as a container
@@ -124,27 +123,27 @@ module Prosereflect
124
123
  remaining_marks = marks[1..]
125
124
 
126
125
  mark_type = if current_mark.is_a?(Hash)
127
- current_mark['type']
126
+ current_mark["type"]
128
127
  elsif current_mark.respond_to?(:type)
129
128
  current_mark.type
130
129
  else
131
- 'unknown'
130
+ "unknown"
132
131
  end
133
132
 
134
133
  case mark_type
135
- when 'bold'
134
+ when "bold"
136
135
  builder.strong do
137
136
  apply_marks(text, remaining_marks, builder)
138
137
  end
139
- when 'italic'
138
+ when "italic"
140
139
  builder.em do
141
140
  apply_marks(text, remaining_marks, builder)
142
141
  end
143
- when 'code'
142
+ when "code"
144
143
  builder.code do
145
144
  apply_marks(text, remaining_marks, builder)
146
145
  end
147
- when 'link'
146
+ when "link"
148
147
  href = find_href_attribute(current_mark)
149
148
  if href
150
149
  builder.a(href: href) do
@@ -153,19 +152,19 @@ module Prosereflect
153
152
  else
154
153
  apply_marks(text, remaining_marks, builder)
155
154
  end
156
- when 'strike'
155
+ when "strike"
157
156
  builder.del do
158
157
  apply_marks(text, remaining_marks, builder)
159
158
  end
160
- when 'underline'
159
+ when "underline"
161
160
  builder.u do
162
161
  apply_marks(text, remaining_marks, builder)
163
162
  end
164
- when 'subscript'
163
+ when "subscript"
165
164
  builder.sub do
166
165
  apply_marks(text, remaining_marks, builder)
167
166
  end
168
- when 'superscript'
167
+ when "superscript"
169
168
  builder.sup do
170
169
  apply_marks(text, remaining_marks, builder)
171
170
  end
@@ -178,23 +177,23 @@ module Prosereflect
178
177
  # Find href attribute in a link mark
179
178
  def find_href_attribute(mark)
180
179
  if mark.is_a?(Hash)
181
- if mark['attrs'].is_a?(Hash)
182
- return mark['attrs']['href']
183
- elsif mark['attrs'].is_a?(Array)
184
- href_attr = mark['attrs'].find { |a| a.is_a?(Prosereflect::Attribute::Href) || (a.is_a?(Hash) && a['type'] == 'href') }
185
- return href_attr['href'] if href_attr.is_a?(Hash) && href_attr['href']
180
+ if mark["attrs"].is_a?(Hash)
181
+ return mark["attrs"]["href"]
182
+ elsif mark["attrs"].is_a?(Array)
183
+ href_attr = mark["attrs"].find { |a| a.is_a?(Prosereflect::Attribute::Href) || (a.is_a?(Hash) && a["type"] == "href") }
184
+ return href_attr["href"] if href_attr.is_a?(Hash) && href_attr["href"]
186
185
  return href_attr.href if href_attr.respond_to?(:href)
187
186
  end
188
187
  elsif mark.respond_to?(:attrs)
189
188
  attrs = mark.attrs
190
189
  if attrs.is_a?(Hash)
191
- return attrs['href']
190
+ return attrs["href"]
192
191
  elsif attrs.is_a?(Array)
193
192
  href_attr = attrs.find { |attr| attr.is_a?(Prosereflect::Attribute::Href) }
194
193
  return href_attr&.href if href_attr
195
194
 
196
- hash_attr = attrs.find { |attr| attr.is_a?(Hash) && attr['href'] }
197
- return hash_attr['href'] if hash_attr
195
+ hash_attr = attrs.find { |attr| attr.is_a?(Hash) && attr["href"] }
196
+ return hash_attr["href"] if hash_attr
198
197
  end
199
198
  end
200
199
  nil
@@ -206,7 +205,9 @@ module Prosereflect
206
205
  rows = node.rows || node.content
207
206
  return if rows.empty?
208
207
 
209
- has_header = rows.first&.content&.any? { |cell| cell.type == 'table_header' }
208
+ has_header = rows.first&.content&.any? do |cell|
209
+ cell.type == "table_header"
210
+ end
210
211
 
211
212
  if has_header
212
213
  builder.thead do
@@ -233,7 +234,7 @@ module Prosereflect
233
234
  # Process a table cell
234
235
  def process_table_cell(node, builder)
235
236
  builder.td do
236
- if node.content&.size == 1 && node.content.first.type == 'paragraph'
237
+ if node.content&.size == 1 && node.content.first.type == "paragraph"
237
238
  node.content.first.content&.each do |child|
238
239
  process_node(child, builder)
239
240
  end
@@ -251,7 +252,7 @@ module Prosereflect
251
252
  attrs[:colspan] = node.colspan if node.colspan
252
253
 
253
254
  builder.th(attrs) do
254
- if node.content&.size == 1 && node.content.first.type == 'paragraph'
255
+ if node.content&.size == 1 && node.content.first.type == "paragraph"
255
256
  node.content.first.content&.each do |child|
256
257
  process_node(child, builder)
257
258
  end
@@ -265,7 +266,7 @@ module Prosereflect
265
266
  def process_image(node, builder)
266
267
  attrs = {
267
268
  src: node.src,
268
- alt: node.alt
269
+ alt: node.alt,
269
270
  }
270
271
  attrs[:title] = node.title if node.title
271
272
  attrs[:width] = node.width if node.width
@@ -283,7 +284,7 @@ module Prosereflect
283
284
  def process_bullet_list(node, builder)
284
285
  builder.ul do
285
286
  node.content&.each do |child|
286
- if child.type == 'list_item'
287
+ if child.type == "list_item"
287
288
  process_node(child, builder)
288
289
  else
289
290
  builder.li do
@@ -330,7 +331,7 @@ module Prosereflect
330
331
  attrs[:style] << "border-style: #{node.style}" if node.style
331
332
  attrs[:style] << "width: #{node.width}" if node.width
332
333
  attrs[:style] << "border-width: #{node.thickness}px" if node.thickness
333
- attrs[:style] = attrs[:style].join('; ') unless attrs[:style].empty?
334
+ attrs[:style] = attrs[:style].join("; ") unless attrs[:style].empty?
334
335
 
335
336
  builder.hr(attrs)
336
337
  end
@@ -339,9 +340,10 @@ module Prosereflect
339
340
  def process_code_block_wrapper(node, builder)
340
341
  attrs = {}
341
342
  if node.attrs
342
- attrs['data-line-numbers'] = 'true' if node.attrs['line_numbers']
343
- if node.attrs['highlight_lines'].is_a?(Array) && !node.attrs['highlight_lines'].empty? && node.attrs['highlight_lines'] != [0]
344
- attrs['data-highlight-lines'] = node.attrs['highlight_lines'].join(',')
343
+ attrs["data-line-numbers"] = "true" if node.attrs["line_numbers"]
344
+ if node.attrs["highlight_lines"].is_a?(Array) && !node.attrs["highlight_lines"].empty? && node.attrs["highlight_lines"] != [0]
345
+ attrs["data-highlight-lines"] =
346
+ node.attrs["highlight_lines"].join(",")
345
347
  end
346
348
  end
347
349
 
@@ -353,7 +355,7 @@ module Prosereflect
353
355
  # Process a code block node
354
356
  def process_code_block(node, builder)
355
357
  attrs = {}
356
- attrs['class'] = "language-#{node.language}" if node.language
358
+ attrs["class"] = "language-#{node.language}" if node.language
357
359
 
358
360
  builder.code(attrs) do
359
361
  builder.text node.content
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prosereflect
4
+ module Output
5
+ autoload :Html, "#{__dir__}/output/html"
6
+ end
7
+ end
@@ -1,20 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'node'
4
- require_relative 'text'
5
- require_relative 'hard_break'
6
-
7
3
  module Prosereflect
8
4
  class Paragraph < Node
9
- PM_TYPE = 'paragraph'
5
+ PM_TYPE = "paragraph"
10
6
 
11
- attribute :type, :string, default: -> { send('const_get', 'PM_TYPE') }
7
+ attribute :type, :string, default: -> {
8
+ self.class.send(:const_get, "PM_TYPE")
9
+ }
12
10
 
13
11
  key_value do
14
- map 'type', to: :type, render_default: true
15
- map 'content', to: :content
16
- map 'attrs', to: :attrs
17
- map 'marks', to: :marks
12
+ map "type", to: :type, render_default: true
13
+ map "content", to: :content
14
+ map "attrs", to: :attrs
15
+ map "marks", to: :marks
18
16
  end
19
17
 
20
18
  def initialize(params = {})
@@ -29,13 +27,13 @@ module Prosereflect
29
27
  def text_nodes
30
28
  return [] unless content
31
29
 
32
- content.select { |node| node.is_a?(Text) }
30
+ content.grep(Text)
33
31
  end
34
32
 
35
33
  def text_content
36
- return '' unless content
34
+ return "" unless content
37
35
 
38
- result = ''
36
+ result = ""
39
37
  content.each do |node|
40
38
  result += node.text_content
41
39
  end