prosereflect 0.1.1 → 0.3.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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +63 -0
  3. data/.github/workflows/links.yml +97 -0
  4. data/.github/workflows/rake.yml +4 -0
  5. data/.github/workflows/release.yml +5 -0
  6. data/.gitignore +4 -0
  7. data/.rubocop.yml +19 -1
  8. data/.rubocop_todo.yml +119 -183
  9. data/CLAUDE.md +78 -0
  10. data/Gemfile +8 -4
  11. data/README.adoc +2 -0
  12. data/Rakefile +3 -3
  13. data/docs/Gemfile +10 -0
  14. data/docs/INDEX.adoc +45 -0
  15. data/docs/_advanced/index.adoc +15 -0
  16. data/docs/_advanced/schema.adoc +112 -0
  17. data/docs/_advanced/step-map.adoc +66 -0
  18. data/docs/_advanced/steps.adoc +88 -0
  19. data/docs/_advanced/test-builder.adoc +61 -0
  20. data/docs/_advanced/transform.adoc +92 -0
  21. data/docs/_config.yml +174 -0
  22. data/docs/_features/html-input.adoc +69 -0
  23. data/docs/_features/html-output.adoc +45 -0
  24. data/docs/_features/index.adoc +15 -0
  25. data/docs/_features/marks.adoc +86 -0
  26. data/docs/_features/node-types.adoc +124 -0
  27. data/docs/_features/user-mentions.adoc +47 -0
  28. data/docs/_guides/custom-nodes.adoc +107 -0
  29. data/docs/_guides/index.adoc +13 -0
  30. data/docs/_guides/round-trip-html.adoc +91 -0
  31. data/docs/_guides/serialization.adoc +109 -0
  32. data/docs/_pages/index.adoc +67 -0
  33. data/docs/_reference/document-api.adoc +49 -0
  34. data/docs/_reference/index.adoc +14 -0
  35. data/docs/_reference/node-api.adoc +79 -0
  36. data/docs/_reference/schema-api.adoc +95 -0
  37. data/docs/_reference/transform-api.adoc +77 -0
  38. data/docs/_understanding/document-model.adoc +65 -0
  39. data/docs/_understanding/fragment.adoc +52 -0
  40. data/docs/_understanding/index.adoc +14 -0
  41. data/docs/_understanding/resolved-position.adoc +53 -0
  42. data/docs/_understanding/slice.adoc +54 -0
  43. data/docs/lychee.toml +63 -0
  44. data/lib/prosereflect/attribute/base.rb +4 -6
  45. data/lib/prosereflect/attribute/bold.rb +2 -4
  46. data/lib/prosereflect/attribute/href.rb +1 -3
  47. data/lib/prosereflect/attribute/id.rb +7 -7
  48. data/lib/prosereflect/attribute.rb +4 -7
  49. data/lib/prosereflect/blockquote.rb +19 -11
  50. data/lib/prosereflect/bullet_list.rb +36 -29
  51. data/lib/prosereflect/code_block.rb +23 -27
  52. data/lib/prosereflect/code_block_wrapper.rb +12 -13
  53. data/lib/prosereflect/document.rb +14 -22
  54. data/lib/prosereflect/fragment.rb +249 -0
  55. data/lib/prosereflect/hard_break.rb +6 -6
  56. data/lib/prosereflect/heading.rb +14 -15
  57. data/lib/prosereflect/horizontal_rule.rb +23 -14
  58. data/lib/prosereflect/image.rb +32 -23
  59. data/lib/prosereflect/input/html.rb +179 -104
  60. data/lib/prosereflect/input.rb +7 -0
  61. data/lib/prosereflect/list_item.rb +11 -12
  62. data/lib/prosereflect/mark/base.rb +9 -11
  63. data/lib/prosereflect/mark/bold.rb +1 -3
  64. data/lib/prosereflect/mark/code.rb +1 -3
  65. data/lib/prosereflect/mark/italic.rb +1 -3
  66. data/lib/prosereflect/mark/link.rb +1 -3
  67. data/lib/prosereflect/mark/strike.rb +1 -3
  68. data/lib/prosereflect/mark/subscript.rb +1 -3
  69. data/lib/prosereflect/mark/superscript.rb +1 -3
  70. data/lib/prosereflect/mark/underline.rb +1 -3
  71. data/lib/prosereflect/mark.rb +9 -5
  72. data/lib/prosereflect/node.rb +171 -33
  73. data/lib/prosereflect/ordered_list.rb +17 -14
  74. data/lib/prosereflect/output/html.rb +279 -50
  75. data/lib/prosereflect/output.rb +7 -0
  76. data/lib/prosereflect/paragraph.rb +11 -13
  77. data/lib/prosereflect/parser.rb +56 -66
  78. data/lib/prosereflect/resolved_pos.rb +256 -0
  79. data/lib/prosereflect/schema/attribute.rb +57 -0
  80. data/lib/prosereflect/schema/content_match.rb +656 -0
  81. data/lib/prosereflect/schema/fragment.rb +166 -0
  82. data/lib/prosereflect/schema/mark.rb +121 -0
  83. data/lib/prosereflect/schema/mark_type.rb +130 -0
  84. data/lib/prosereflect/schema/node.rb +236 -0
  85. data/lib/prosereflect/schema/node_type.rb +274 -0
  86. data/lib/prosereflect/schema/schema_main.rb +190 -0
  87. data/lib/prosereflect/schema/spec.rb +92 -0
  88. data/lib/prosereflect/schema.rb +39 -0
  89. data/lib/prosereflect/table.rb +12 -13
  90. data/lib/prosereflect/table_cell.rb +13 -13
  91. data/lib/prosereflect/table_header.rb +17 -17
  92. data/lib/prosereflect/table_row.rb +12 -12
  93. data/lib/prosereflect/text.rb +35 -11
  94. data/lib/prosereflect/transform/attr_step.rb +157 -0
  95. data/lib/prosereflect/transform/insert_step.rb +115 -0
  96. data/lib/prosereflect/transform/mapping.rb +82 -0
  97. data/lib/prosereflect/transform/mark_step.rb +269 -0
  98. data/lib/prosereflect/transform/replace_around_step.rb +181 -0
  99. data/lib/prosereflect/transform/replace_step.rb +157 -0
  100. data/lib/prosereflect/transform/slice.rb +91 -0
  101. data/lib/prosereflect/transform/step.rb +89 -0
  102. data/lib/prosereflect/transform/step_map.rb +126 -0
  103. data/lib/prosereflect/transform/structure.rb +120 -0
  104. data/lib/prosereflect/transform/transform.rb +341 -0
  105. data/lib/prosereflect/transform.rb +26 -0
  106. data/lib/prosereflect/user.rb +15 -15
  107. data/lib/prosereflect/version.rb +1 -1
  108. data/lib/prosereflect.rb +30 -17
  109. data/prosereflect.gemspec +17 -16
  110. data/spec/fixtures/documents/formatted_text.yaml +14 -0
  111. data/spec/fixtures/documents/heading_paragraph.yaml +16 -0
  112. data/spec/fixtures/documents/lists_doc.yaml +32 -0
  113. data/spec/fixtures/documents/mixed_content.yaml +40 -0
  114. data/spec/fixtures/documents/nested_doc.yaml +20 -0
  115. data/spec/fixtures/documents/simple_doc.yaml +6 -0
  116. data/spec/fixtures/documents/table_doc.yaml +32 -0
  117. data/spec/fixtures/documents/transform_test.yaml +14 -0
  118. data/spec/fixtures/schema/custom_schema.rb +37 -0
  119. data/spec/fixtures/schema/test_schema.rb +46 -0
  120. data/spec/fixtures/test_builder/helpers.rb +212 -0
  121. data/spec/prosereflect/document_spec.rb +332 -330
  122. data/spec/prosereflect/fragment_spec.rb +273 -0
  123. data/spec/prosereflect/hard_break_spec.rb +125 -125
  124. data/spec/prosereflect/input/html_spec.rb +718 -522
  125. data/spec/prosereflect/node_spec.rb +311 -182
  126. data/spec/prosereflect/output/html_spec.rb +105 -105
  127. data/spec/prosereflect/output/whitespace_spec.rb +248 -0
  128. data/spec/prosereflect/paragraph_spec.rb +275 -274
  129. data/spec/prosereflect/parser/round_trip_spec.rb +472 -0
  130. data/spec/prosereflect/parser_spec.rb +185 -180
  131. data/spec/prosereflect/resolved_pos_spec.rb +74 -0
  132. data/spec/prosereflect/schema/conftest.rb +68 -0
  133. data/spec/prosereflect/schema/content_match_spec.rb +237 -0
  134. data/spec/prosereflect/schema/mark_spec.rb +274 -0
  135. data/spec/prosereflect/schema/mark_type_spec.rb +86 -0
  136. data/spec/prosereflect/schema/node_type_spec.rb +142 -0
  137. data/spec/prosereflect/schema/schema_spec.rb +194 -0
  138. data/spec/prosereflect/table_cell_spec.rb +183 -183
  139. data/spec/prosereflect/table_row_spec.rb +149 -149
  140. data/spec/prosereflect/table_spec.rb +320 -318
  141. data/spec/prosereflect/test_builder/marks_spec.rb +127 -0
  142. data/spec/prosereflect/text_spec.rb +133 -132
  143. data/spec/prosereflect/transform/equivalence_spec.rb +487 -0
  144. data/spec/prosereflect/transform/mapping_spec.rb +226 -0
  145. data/spec/prosereflect/transform/replace_spec.rb +832 -0
  146. data/spec/prosereflect/transform/replace_step_spec.rb +157 -0
  147. data/spec/prosereflect/transform/slice_spec.rb +48 -0
  148. data/spec/prosereflect/transform/step_map_spec.rb +70 -0
  149. data/spec/prosereflect/transform/step_spec.rb +211 -0
  150. data/spec/prosereflect/transform/structure_spec.rb +98 -0
  151. data/spec/prosereflect/transform/transform_spec.rb +238 -0
  152. data/spec/prosereflect/user_spec.rb +31 -28
  153. data/spec/prosereflect_spec.rb +28 -26
  154. data/spec/spec_helper.rb +7 -6
  155. data/spec/support/matchers.rb +6 -6
  156. data/spec/support/shared_examples.rb +49 -49
  157. metadata +96 -5
  158. data/spec/prosereflect/version_spec.rb +0 -11
@@ -1,53 +1,53 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  RSpec.describe Prosereflect::Output::Html do
6
- describe '.convert' do
7
- it 'converts a simple document to HTML' do
6
+ describe ".convert" do
7
+ it "converts a simple document to HTML" do
8
8
  document = Prosereflect::Document.new
9
- document.add_paragraph('This is a test paragraph.')
9
+ document.add_paragraph("This is a test paragraph.")
10
10
 
11
11
  html = described_class.convert(document)
12
- expect(html).to eq('<p>This is a test paragraph.</p>')
12
+ expect(html).to eq("<p>This is a test paragraph.</p>")
13
13
  end
14
14
 
15
- it 'renders basic styled text correctly' do
15
+ it "renders basic styled text correctly" do
16
16
  document = Prosereflect::Document.new
17
17
  paragraph = document.add_paragraph
18
- paragraph.add_text('This is ')
18
+ paragraph.add_text("This is ")
19
19
 
20
- bold_text = Prosereflect::Text.new(text: 'bold')
20
+ bold_text = Prosereflect::Text.new(text: "bold")
21
21
  bold_text.marks = [Prosereflect::Mark::Bold.new]
22
22
  paragraph.add_child(bold_text)
23
23
 
24
- paragraph.add_text(' and ')
24
+ paragraph.add_text(" and ")
25
25
 
26
- italic_text = Prosereflect::Text.new(text: 'italic')
26
+ italic_text = Prosereflect::Text.new(text: "italic")
27
27
  italic_text.marks = [Prosereflect::Mark::Italic.new]
28
28
  paragraph.add_child(italic_text)
29
29
 
30
- paragraph.add_text(' text.')
30
+ paragraph.add_text(" text.")
31
31
 
32
32
  html = described_class.convert(document)
33
- expect(html).to eq('<p>This is <strong>bold</strong> and <em>italic</em> text.</p>')
33
+ expect(html).to eq("<p>This is <strong>bold</strong> and <em>italic</em> text.</p>")
34
34
  end
35
35
 
36
- it 'renders headings with mixed content correctly' do
36
+ it "renders headings with mixed content correctly" do
37
37
  document = Prosereflect::Document.new
38
38
  heading = Prosereflect::Heading.new
39
39
  heading.level = 1
40
- heading.add_text('Title with ')
40
+ heading.add_text("Title with ")
41
41
 
42
- bold_text = Prosereflect::Text.new(text: 'bold')
42
+ bold_text = Prosereflect::Text.new(text: "bold")
43
43
  bold_text.marks = [Prosereflect::Mark::Bold.new]
44
44
  heading.add_child(bold_text)
45
45
 
46
- heading.add_text(' and ')
46
+ heading.add_text(" and ")
47
47
 
48
- link_text = Prosereflect::Text.new(text: 'link')
48
+ link_text = Prosereflect::Text.new(text: "link")
49
49
  link_mark = Prosereflect::Mark::Link.new
50
- link_mark.attrs = { 'href' => 'https://example.com' }
50
+ link_mark.attrs = { "href" => "https://example.com" }
51
51
  link_text.marks = [link_mark]
52
52
  heading.add_child(link_text)
53
53
 
@@ -57,15 +57,15 @@ RSpec.describe Prosereflect::Output::Html do
57
57
  expect(html).to eq('<h1>Title with <strong>bold</strong> and <a href="https://example.com">link</a></h1>')
58
58
  end
59
59
 
60
- it 'renders lists with nested content correctly' do
60
+ it "renders lists with nested content correctly" do
61
61
  document = Prosereflect::Document.new
62
62
  list = Prosereflect::BulletList.new
63
63
 
64
64
  # First item with emphasis
65
65
  item1 = Prosereflect::ListItem.new
66
66
  para1 = item1.add_paragraph
67
- para1.add_text('First item with ')
68
- em_text = Prosereflect::Text.new(text: 'emphasis')
67
+ para1.add_text("First item with ")
68
+ em_text = Prosereflect::Text.new(text: "emphasis")
69
69
  em_text.marks = [Prosereflect::Mark::Italic.new]
70
70
  para1.add_child(em_text)
71
71
  list.add_child(item1)
@@ -73,8 +73,8 @@ RSpec.describe Prosereflect::Output::Html do
73
73
  # Second item with code
74
74
  item2 = Prosereflect::ListItem.new
75
75
  para2 = item2.add_paragraph
76
- para2.add_text('Second item with ')
77
- code_text = Prosereflect::Text.new(text: 'code')
76
+ para2.add_text("Second item with ")
77
+ code_text = Prosereflect::Text.new(text: "code")
78
78
  code_text.marks = [Prosereflect::Mark::Code.new]
79
79
  para2.add_child(code_text)
80
80
  list.add_child(item2)
@@ -82,19 +82,19 @@ RSpec.describe Prosereflect::Output::Html do
82
82
  document.add_child(list)
83
83
 
84
84
  html = described_class.convert(document)
85
- expect(html).to eq('<ul><li><p>First item with <em>emphasis</em></p></li><li><p>Second item with <code>code</code></p></li></ul>')
85
+ expect(html).to eq("<ul><li><p>First item with <em>emphasis</em></p></li><li><p>Second item with <code>code</code></p></li></ul>")
86
86
  end
87
87
 
88
- it 'renders blockquotes with citations correctly' do
88
+ it "renders blockquotes with citations correctly" do
89
89
  document = Prosereflect::Document.new
90
90
  quote = Prosereflect::Blockquote.new
91
- quote.citation = 'https://example.com'
91
+ quote.citation = "https://example.com"
92
92
 
93
- para = quote.add_paragraph('A quote with ')
94
- bold_text = Prosereflect::Text.new(text: 'bold')
93
+ para = quote.add_paragraph("A quote with ")
94
+ bold_text = Prosereflect::Text.new(text: "bold")
95
95
  bold_text.marks = [Prosereflect::Mark::Bold.new]
96
96
  para.add_child(bold_text)
97
- para.add_text(' text')
97
+ para.add_text(" text")
98
98
 
99
99
  document.add_child(quote)
100
100
 
@@ -102,12 +102,12 @@ RSpec.describe Prosereflect::Output::Html do
102
102
  expect(html).to eq('<blockquote cite="https://example.com"><p>A quote with <strong>bold</strong> text</p></blockquote>')
103
103
  end
104
104
 
105
- it 'renders code blocks with language correctly' do
105
+ it "renders code blocks with language correctly" do
106
106
  document = Prosereflect::Document.new
107
107
  wrapper = Prosereflect::CodeBlockWrapper.new
108
108
 
109
109
  code_block = wrapper.add_code_block
110
- code_block.language = 'ruby'
110
+ code_block.language = "ruby"
111
111
  code_block.content = "def example\n puts \"Hello\"\nend"
112
112
 
113
113
  document.add_child(wrapper)
@@ -119,15 +119,15 @@ RSpec.describe Prosereflect::Output::Html do
119
119
  HTML
120
120
 
121
121
  html = described_class.convert(document)
122
- expect(html).to eq(expected.gsub(/^ {10}/, ' '))
122
+ expect(html).to eq(expected.gsub(/^ {10}/, " "))
123
123
  end
124
124
 
125
- it 'renders images with attributes correctly' do
125
+ it "renders images with attributes correctly" do
126
126
  document = Prosereflect::Document.new
127
127
  image = Prosereflect::Image.new
128
- image.src = 'test.jpg'
129
- image.alt = 'Test image'
130
- image.title = 'Test title'
128
+ image.src = "test.jpg"
129
+ image.alt = "Test image"
130
+ image.title = "Test title"
131
131
  image.width = 800
132
132
  image.height = 600
133
133
 
@@ -137,11 +137,11 @@ RSpec.describe Prosereflect::Output::Html do
137
137
  expect(html).to eq('<img src="test.jpg" alt="Test image" title="Test title" width="800" height="600">')
138
138
  end
139
139
 
140
- it 'renders horizontal rules with styles correctly' do
140
+ it "renders horizontal rules with styles correctly" do
141
141
  document = Prosereflect::Document.new
142
142
  hr = Prosereflect::HorizontalRule.new
143
- hr.style = 'dashed'
144
- hr.width = '80%'
143
+ hr.style = "dashed"
144
+ hr.width = "80%"
145
145
  hr.thickness = 2
146
146
 
147
147
  document.add_child(hr)
@@ -150,13 +150,13 @@ RSpec.describe Prosereflect::Output::Html do
150
150
  expect(html).to eq('<hr style="border-style: dashed; width: 80%; border-width: 2px">')
151
151
  end
152
152
 
153
- it 'renders complex nested structures correctly' do
153
+ it "renders complex nested structures correctly" do
154
154
  document = Prosereflect::Document.new
155
155
 
156
156
  # Add heading
157
157
  heading = Prosereflect::Heading.new
158
158
  heading.level = 2
159
- heading.add_text('Features')
159
+ heading.add_text("Features")
160
160
  document.add_child(heading)
161
161
 
162
162
  # Add list with nested content
@@ -165,69 +165,69 @@ RSpec.describe Prosereflect::Output::Html do
165
165
  # List item with blockquote
166
166
  item1 = Prosereflect::ListItem.new
167
167
  para1 = item1.add_paragraph
168
- para1.add_text('Quote: ')
168
+ para1.add_text("Quote: ")
169
169
  list.add_child(item1)
170
170
 
171
171
  quote = Prosereflect::Blockquote.new
172
- quote.citation = 'https://example.com'
173
- quote.add_paragraph('Nested quote')
172
+ quote.citation = "https://example.com"
173
+ quote.add_paragraph("Nested quote")
174
174
  list.add_child(quote)
175
175
 
176
176
  # List item with code
177
177
  item2 = Prosereflect::ListItem.new
178
178
  para2 = item2.add_paragraph
179
- para2.add_text('Code: ')
179
+ para2.add_text("Code: ")
180
180
  list.add_child(item2)
181
181
 
182
182
  wrapper = Prosereflect::CodeBlockWrapper.new
183
183
  code_block = wrapper.add_code_block
184
- code_block.language = 'ruby'
184
+ code_block.language = "ruby"
185
185
  code_block.content = 'puts "Hello"'
186
186
  list.add_child(wrapper)
187
187
 
188
188
  document.add_child(list)
189
189
 
190
190
  html = described_class.convert(document)
191
- expected = '<h2>Features</h2>' \
192
- '<ul>' \
193
- '<li><p>Quote: </p></li>' \
194
- '<li><blockquote cite="https://example.com"><p>Nested quote</p></blockquote></li>' \
195
- '<li><p>Code: </p></li>' \
196
- '<li><pre><code class="language-ruby">puts "Hello"</code></pre></li>' \
197
- '</ul>'
191
+ expected = "<h2>Features</h2>" \
192
+ "<ul>" \
193
+ "<li><p>Quote: </p></li>" \
194
+ '<li><blockquote cite="https://example.com"><p>Nested quote</p></blockquote></li>' \
195
+ "<li><p>Code: </p></li>" \
196
+ '<li><pre><code class="language-ruby">puts "Hello"</code></pre></li>' \
197
+ "</ul>"
198
198
  expect(html).to eq(expected)
199
199
  end
200
200
 
201
- it 'converts tables to HTML' do
201
+ it "converts tables to HTML" do
202
202
  document = Prosereflect::Document.new
203
203
  table = document.add_table
204
204
 
205
205
  # Add header row
206
- table.add_header(['Header 1', 'Header 2'])
206
+ table.add_header(["Header 1", "Header 2"])
207
207
 
208
208
  # Add data rows
209
- table.add_row(['Row 1, Cell 1', 'Row 1, Cell 2'])
210
- table.add_row(['Row 2, Cell 1', 'Row 2, Cell 2'])
209
+ table.add_row(["Row 1, Cell 1", "Row 1, Cell 2"])
210
+ table.add_row(["Row 2, Cell 1", "Row 2, Cell 2"])
211
211
 
212
212
  html = described_class.convert(document)
213
- expected = '<table>' \
214
- '<thead><tr><th>Header 1</th><th>Header 2</th></tr></thead>' \
215
- '<tbody>' \
216
- '<tr><td>Row 1, Cell 1</td><td>Row 1, Cell 2</td></tr>' \
217
- '<tr><td>Row 2, Cell 1</td><td>Row 2, Cell 2</td></tr>' \
218
- '</tbody>' \
219
- '</table>'
213
+ expected = "<table>" \
214
+ "<thead><tr><th>Header 1</th><th>Header 2</th></tr></thead>" \
215
+ "<tbody>" \
216
+ "<tr><td>Row 1, Cell 1</td><td>Row 1, Cell 2</td></tr>" \
217
+ "<tr><td>Row 2, Cell 1</td><td>Row 2, Cell 2</td></tr>" \
218
+ "</tbody>" \
219
+ "</table>"
220
220
  expect(html).to eq(expected)
221
221
  end
222
222
 
223
- it 'converts complex table headers' do
223
+ it "converts complex table headers" do
224
224
  document = Prosereflect::Document.new
225
225
  table = document.add_table
226
226
 
227
227
  # Add header row with complex cells
228
- header = table.add_header(['Product'])
229
- header.cells.first.scope = 'col'
230
- header.cells.first.abbr = 'Prod'
228
+ header = table.add_header(["Product"])
229
+ header.cells.first.scope = "col"
230
+ header.cells.first.abbr = "Prod"
231
231
  header.cells.first.colspan = 2
232
232
 
233
233
  html = described_class.convert(document)
@@ -235,26 +235,26 @@ RSpec.describe Prosereflect::Output::Html do
235
235
  expect(html).to eq(expected)
236
236
  end
237
237
 
238
- it 'converts text with all mark types' do
238
+ it "converts text with all mark types" do
239
239
  document = Prosereflect::Document.new
240
240
  paragraph = document.add_paragraph
241
241
 
242
- paragraph.add_text('struck', [Prosereflect::Mark::Strike.new])
243
- paragraph.add_text(' and ')
244
- paragraph.add_text('underlined', [Prosereflect::Mark::Underline.new])
245
- paragraph.add_text(' and ')
246
- paragraph.add_text('sub', [Prosereflect::Mark::Subscript.new])
247
- paragraph.add_text(' and ')
248
- paragraph.add_text('super', [Prosereflect::Mark::Superscript.new])
242
+ paragraph.add_text("struck", [Prosereflect::Mark::Strike.new])
243
+ paragraph.add_text(" and ")
244
+ paragraph.add_text("underlined", [Prosereflect::Mark::Underline.new])
245
+ paragraph.add_text(" and ")
246
+ paragraph.add_text("sub", [Prosereflect::Mark::Subscript.new])
247
+ paragraph.add_text(" and ")
248
+ paragraph.add_text("super", [Prosereflect::Mark::Superscript.new])
249
249
 
250
250
  html = described_class.convert(document)
251
- expect(html).to eq('<p><del>struck</del> and <u>underlined</u> and <sub>sub</sub> and <sup>super</sup></p>')
251
+ expect(html).to eq("<p><del>struck</del> and <u>underlined</u> and <sub>sub</sub> and <sup>super</sup></p>")
252
252
  end
253
253
 
254
- it 'converts images with all attributes' do
254
+ it "converts images with all attributes" do
255
255
  document = Prosereflect::Document.new
256
- image = document.add_image('example.jpg', 'Example image')
257
- image.title = 'Image tooltip'
256
+ image = document.add_image("example.jpg", "Example image")
257
+ image.title = "Image tooltip"
258
258
  image.width = 800
259
259
  image.height = 600
260
260
 
@@ -262,13 +262,13 @@ RSpec.describe Prosereflect::Output::Html do
262
262
  expect(html).to eq('<img src="example.jpg" alt="Example image" title="Image tooltip" width="800" height="600">')
263
263
  end
264
264
 
265
- it 'converts code blocks with wrapper attributes' do
265
+ it "converts code blocks with wrapper attributes" do
266
266
  document = Prosereflect::Document.new
267
267
  wrapper = document.add_code_block_wrapper
268
268
  wrapper.line_numbers = true
269
269
 
270
270
  code_block = wrapper.add_code_block
271
- code_block.language = 'ruby'
271
+ code_block.language = "ruby"
272
272
  code_block.content = "def example\n puts 'Hello'\nend"
273
273
 
274
274
  html = described_class.convert(document)
@@ -278,87 +278,87 @@ end</code></pre>'
278
278
  expect(html).to eq(expected)
279
279
  end
280
280
 
281
- it 'handles complex nested structures with tables' do
281
+ it "handles complex nested structures with tables" do
282
282
  document = Prosereflect::Document.new
283
283
 
284
284
  # Add a paragraph with styled text
285
- document.add_paragraph('Paragraph 1')
285
+ document.add_paragraph("Paragraph 1")
286
286
 
287
287
  # Add a paragraph with mixed styling
288
288
  p2 = document.add_paragraph
289
- p2.add_text('Paragraph ')
290
- p2.add_text('2', [Prosereflect::Mark::Bold.new])
289
+ p2.add_text("Paragraph ")
290
+ p2.add_text("2", [Prosereflect::Mark::Bold.new])
291
291
 
292
292
  # Add a table
293
293
  table = document.add_table
294
- table.add_row(['Cell 1', 'Cell 2'])
294
+ table.add_row(["Cell 1", "Cell 2"])
295
295
 
296
296
  html = described_class.convert(document)
297
- expected = '<p>Paragraph 1</p><p>Paragraph <strong>2</strong></p><table><tbody><tr><td>Cell 1</td><td>Cell 2</td></tr></tbody></table>'
297
+ expected = "<p>Paragraph 1</p><p>Paragraph <strong>2</strong></p><table><tbody><tr><td>Cell 1</td><td>Cell 2</td></tr></tbody></table>"
298
298
  expect(html).to eq(expected)
299
299
  end
300
300
 
301
- it 'renders user mentions correctly' do
301
+ it "renders user mentions correctly" do
302
302
  document = Prosereflect::Document.new
303
303
  user = Prosereflect::User.new
304
- user.id = '123'
304
+ user.id = "123"
305
305
  document.add_child(user)
306
306
 
307
307
  html = described_class.convert(document)
308
308
  expect(html).to eq('<user-mention data-id="123"></user-mention>')
309
309
  end
310
310
 
311
- it 'renders user mentions in paragraphs' do
311
+ it "renders user mentions in paragraphs" do
312
312
  document = Prosereflect::Document.new
313
313
  paragraph = document.add_paragraph
314
- paragraph.add_text('Hello ')
314
+ paragraph.add_text("Hello ")
315
315
 
316
316
  user = Prosereflect::User.new
317
- user.id = '123'
317
+ user.id = "123"
318
318
  paragraph.add_child(user)
319
319
 
320
- paragraph.add_text('!')
320
+ paragraph.add_text("!")
321
321
 
322
322
  html = described_class.convert(document)
323
323
  expect(html).to eq('<p>Hello <user-mention data-id="123"></user-mention>!</p>')
324
324
  end
325
325
 
326
- it 'renders multiple user mentions' do
326
+ it "renders multiple user mentions" do
327
327
  document = Prosereflect::Document.new
328
328
  paragraph = document.add_paragraph
329
- paragraph.add_text('Mentioned: ')
329
+ paragraph.add_text("Mentioned: ")
330
330
 
331
331
  user1 = Prosereflect::User.new
332
- user1.id = '123'
332
+ user1.id = "123"
333
333
  paragraph.add_child(user1)
334
334
 
335
- paragraph.add_text(' and ')
335
+ paragraph.add_text(" and ")
336
336
 
337
337
  user2 = Prosereflect::User.new
338
- user2.id = '456'
338
+ user2.id = "456"
339
339
  paragraph.add_child(user2)
340
340
 
341
341
  html = described_class.convert(document)
342
342
  expect(html).to eq('<p>Mentioned: <user-mention data-id="123"></user-mention> and <user-mention data-id="456"></user-mention></p>')
343
343
  end
344
344
 
345
- it 'renders user mentions with other marks' do
345
+ it "renders user mentions with other marks" do
346
346
  document = Prosereflect::Document.new
347
347
  paragraph = document.add_paragraph
348
348
 
349
- bold_text = Prosereflect::Text.new(text: 'Bold')
349
+ bold_text = Prosereflect::Text.new(text: "Bold")
350
350
  bold_text.marks = [Prosereflect::Mark::Bold.new]
351
351
  paragraph.add_child(bold_text)
352
352
 
353
- paragraph.add_text(' and ')
353
+ paragraph.add_text(" and ")
354
354
 
355
355
  user = Prosereflect::User.new
356
- user.id = '123'
356
+ user.id = "123"
357
357
  paragraph.add_child(user)
358
358
 
359
- paragraph.add_text(' and ')
359
+ paragraph.add_text(" and ")
360
360
 
361
- italic_text = Prosereflect::Text.new(text: 'italic')
361
+ italic_text = Prosereflect::Text.new(text: "italic")
362
362
  italic_text.marks = [Prosereflect::Mark::Italic.new]
363
363
  paragraph.add_child(italic_text)
364
364