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,309 +1,309 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  RSpec.describe Prosereflect::TableCell do
6
- describe 'initialization' do
7
- it 'initializes as a table_cell node' do
8
- cell = described_class.new({ 'type' => 'table_cell' })
9
- expect(cell.type).to eq('table_cell')
6
+ describe "initialization" do
7
+ it "initializes as a table_cell node" do
8
+ cell = described_class.new({ "type" => "table_cell" })
9
+ expect(cell.type).to eq("table_cell")
10
10
  end
11
11
  end
12
12
 
13
- describe '.create' do
14
- it 'creates an empty table cell' do
13
+ describe ".create" do
14
+ it "creates an empty table cell" do
15
15
  cell = described_class.create
16
16
 
17
17
  expected = {
18
- 'type' => 'table_cell',
19
- 'content' => []
18
+ "type" => "table_cell",
19
+ "content" => [],
20
20
  }
21
21
 
22
22
  expect(cell.to_h).to eq(expected)
23
23
  end
24
24
 
25
- it 'creates a table cell with attributes' do
25
+ it "creates a table cell with attributes" do
26
26
  cell = described_class.create(attrs: {
27
- 'colspan' => 2,
28
- 'rowspan' => 1,
29
- 'background' => '#f5f5f5',
30
- 'align' => 'center',
31
- 'valign' => 'middle'
27
+ "colspan" => 2,
28
+ "rowspan" => 1,
29
+ "background" => "#f5f5f5",
30
+ "align" => "center",
31
+ "valign" => "middle",
32
32
  })
33
33
 
34
34
  expected = {
35
- 'type' => 'table_cell',
36
- 'attrs' => {
37
- 'colspan' => 2,
38
- 'rowspan' => 1,
39
- 'background' => '#f5f5f5',
40
- 'align' => 'center',
41
- 'valign' => 'middle'
35
+ "type" => "table_cell",
36
+ "attrs" => {
37
+ "colspan" => 2,
38
+ "rowspan" => 1,
39
+ "background" => "#f5f5f5",
40
+ "align" => "center",
41
+ "valign" => "middle",
42
42
  },
43
- 'content' => []
43
+ "content" => [],
44
44
  }
45
45
 
46
46
  expect(cell.to_h).to eq(expected)
47
47
  end
48
48
  end
49
49
 
50
- describe 'cell structure' do
51
- it 'creates a cell with simple text content' do
50
+ describe "cell structure" do
51
+ it "creates a cell with simple text content" do
52
52
  cell = described_class.create
53
- cell.add_paragraph('Simple text')
53
+ cell.add_paragraph("Simple text")
54
54
 
55
55
  expected = {
56
- 'type' => 'table_cell',
57
- 'content' => [{
58
- 'type' => 'paragraph',
59
- 'content' => [{
60
- 'type' => 'text',
61
- 'text' => 'Simple text'
62
- }]
63
- }]
56
+ "type" => "table_cell",
57
+ "content" => [{
58
+ "type" => "paragraph",
59
+ "content" => [{
60
+ "type" => "text",
61
+ "text" => "Simple text",
62
+ }],
63
+ }],
64
64
  }
65
65
 
66
66
  expect(cell.to_h).to eq(expected)
67
67
  end
68
68
 
69
- it 'creates a cell with complex content' do
69
+ it "creates a cell with complex content" do
70
70
  cell = described_class.create
71
71
 
72
72
  # First paragraph with mixed formatting
73
- para = cell.add_paragraph('This is ')
74
- para.add_text('bold', [Prosereflect::Mark::Bold.new])
75
- para.add_text(' and ')
76
- para.add_text('italic', [Prosereflect::Mark::Italic.new])
73
+ para = cell.add_paragraph("This is ")
74
+ para.add_text("bold", [Prosereflect::Mark::Bold.new])
75
+ para.add_text(" and ")
76
+ para.add_text("italic", [Prosereflect::Mark::Italic.new])
77
77
  para.add_hard_break
78
- para.add_text('with a line break')
78
+ para.add_text("with a line break")
79
79
 
80
80
  # Second paragraph with more formatting
81
81
  para = cell.add_paragraph
82
- para.add_text('Status: ', [Prosereflect::Mark::Bold.new])
83
- para.add_text('Done', [Prosereflect::Mark::Strike.new])
84
- para.add_text('')
85
- para.add_text('In Progress', [Prosereflect::Mark::Italic.new])
82
+ para.add_text("Status: ", [Prosereflect::Mark::Bold.new])
83
+ para.add_text("Done", [Prosereflect::Mark::Strike.new])
84
+ para.add_text("")
85
+ para.add_text("In Progress", [Prosereflect::Mark::Italic.new])
86
86
 
87
87
  expected = {
88
- 'type' => 'table_cell',
89
- 'content' => [{
90
- 'type' => 'paragraph',
91
- 'content' => [{
92
- 'type' => 'text',
93
- 'text' => 'This is '
88
+ "type" => "table_cell",
89
+ "content" => [{
90
+ "type" => "paragraph",
91
+ "content" => [{
92
+ "type" => "text",
93
+ "text" => "This is ",
94
94
  }, {
95
- 'type' => 'text',
96
- 'text' => 'bold',
97
- 'marks' => [{
98
- 'type' => 'bold'
99
- }]
95
+ "type" => "text",
96
+ "text" => "bold",
97
+ "marks" => [{
98
+ "type" => "bold",
99
+ }],
100
100
  }, {
101
- 'type' => 'text',
102
- 'text' => ' and '
101
+ "type" => "text",
102
+ "text" => " and ",
103
103
  }, {
104
- 'type' => 'text',
105
- 'text' => 'italic',
106
- 'marks' => [{
107
- 'type' => 'italic'
108
- }]
104
+ "type" => "text",
105
+ "text" => "italic",
106
+ "marks" => [{
107
+ "type" => "italic",
108
+ }],
109
109
  }, {
110
- 'type' => 'hard_break'
110
+ "type" => "hard_break",
111
111
  }, {
112
- 'type' => 'text',
113
- 'text' => 'with a line break'
114
- }]
112
+ "type" => "text",
113
+ "text" => "with a line break",
114
+ }],
115
115
  }, {
116
- 'type' => 'paragraph',
117
- 'content' => [{
118
- 'type' => 'text',
119
- 'text' => 'Status: ',
120
- 'marks' => [{
121
- 'type' => 'bold'
122
- }]
116
+ "type" => "paragraph",
117
+ "content" => [{
118
+ "type" => "text",
119
+ "text" => "Status: ",
120
+ "marks" => [{
121
+ "type" => "bold",
122
+ }],
123
123
  }, {
124
- 'type' => 'text',
125
- 'text' => 'Done',
126
- 'marks' => [{
127
- 'type' => 'strike'
128
- }]
124
+ "type" => "text",
125
+ "text" => "Done",
126
+ "marks" => [{
127
+ "type" => "strike",
128
+ }],
129
129
  }, {
130
- 'type' => 'text',
131
- 'text' => ''
130
+ "type" => "text",
131
+ "text" => "",
132
132
  }, {
133
- 'type' => 'text',
134
- 'text' => 'In Progress',
135
- 'marks' => [{
136
- 'type' => 'italic'
137
- }]
138
- }]
139
- }]
133
+ "type" => "text",
134
+ "text" => "In Progress",
135
+ "marks" => [{
136
+ "type" => "italic",
137
+ }],
138
+ }],
139
+ }],
140
140
  }
141
141
 
142
142
  expect(cell.to_h).to eq(expected)
143
143
  end
144
144
  end
145
145
 
146
- describe 'cell operations' do
146
+ describe "cell operations" do
147
147
  let(:cell) do
148
148
  c = described_class.create
149
- c.add_paragraph('First paragraph')
150
- c.add_paragraph('Second paragraph')
151
- c.add_paragraph('Third paragraph')
149
+ c.add_paragraph("First paragraph")
150
+ c.add_paragraph("Second paragraph")
151
+ c.add_paragraph("Third paragraph")
152
152
  c
153
153
  end
154
154
 
155
- describe '#paragraphs' do
156
- it 'returns all paragraphs in the cell' do
155
+ describe "#paragraphs" do
156
+ it "returns all paragraphs in the cell" do
157
157
  expect(cell.paragraphs.size).to eq(3)
158
158
  expect(cell.paragraphs).to all(be_a(Prosereflect::Paragraph))
159
159
  expect(cell.paragraphs.map(&:text_content)).to eq([
160
- 'First paragraph',
161
- 'Second paragraph',
162
- 'Third paragraph'
160
+ "First paragraph",
161
+ "Second paragraph",
162
+ "Third paragraph",
163
163
  ])
164
164
  end
165
165
 
166
- it 'returns empty array for cell with no paragraphs' do
166
+ it "returns empty array for cell with no paragraphs" do
167
167
  empty_cell = described_class.create
168
168
  expect(empty_cell.paragraphs).to eq([])
169
169
  end
170
170
  end
171
171
 
172
- describe '#text_content' do
173
- it 'returns concatenated text from all paragraphs with newlines' do
172
+ describe "#text_content" do
173
+ it "returns concatenated text from all paragraphs with newlines" do
174
174
  expect(cell.text_content).to eq("First paragraph\nSecond paragraph\nThird paragraph")
175
175
  end
176
176
 
177
- it 'returns empty string for empty cell' do
177
+ it "returns empty string for empty cell" do
178
178
  empty_cell = described_class.create
179
- expect(empty_cell.text_content).to eq('')
179
+ expect(empty_cell.text_content).to eq("")
180
180
  end
181
181
 
182
- it 'handles complex formatting and line breaks' do
182
+ it "handles complex formatting and line breaks" do
183
183
  cell = described_class.create
184
- para = cell.add_paragraph('Line 1')
184
+ para = cell.add_paragraph("Line 1")
185
185
  para.add_hard_break
186
- para.add_text('Line 2', [Prosereflect::Mark::Bold.new])
186
+ para.add_text("Line 2", [Prosereflect::Mark::Bold.new])
187
187
  para.add_hard_break
188
- para.add_text('Line 3', [Prosereflect::Mark::Italic.new])
188
+ para.add_text("Line 3", [Prosereflect::Mark::Italic.new])
189
189
 
190
190
  expect(cell.text_content).to eq("Line 1\nLine 2\nLine 3")
191
191
  end
192
192
  end
193
193
 
194
- describe '#lines' do
195
- it 'splits text content into lines' do
194
+ describe "#lines" do
195
+ it "splits text content into lines" do
196
196
  expect(cell.lines).to eq([
197
- 'First paragraph',
198
- 'Second paragraph',
199
- 'Third paragraph'
197
+ "First paragraph",
198
+ "Second paragraph",
199
+ "Third paragraph",
200
200
  ])
201
201
  end
202
202
 
203
- it 'returns empty array for empty cell' do
203
+ it "returns empty array for empty cell" do
204
204
  empty_cell = described_class.create
205
205
  expect(empty_cell.lines).to eq([])
206
206
  end
207
207
 
208
- it 'handles hard breaks within paragraphs' do
208
+ it "handles hard breaks within paragraphs" do
209
209
  cell = described_class.create
210
- para = cell.add_paragraph('First line')
210
+ para = cell.add_paragraph("First line")
211
211
  para.add_hard_break
212
- para.add_text('Second line')
213
- cell.add_paragraph('Third line')
212
+ para.add_text("Second line")
213
+ cell.add_paragraph("Third line")
214
214
 
215
215
  expect(cell.lines).to eq([
216
- 'First line',
217
- 'Second line',
218
- 'Third line'
216
+ "First line",
217
+ "Second line",
218
+ "Third line",
219
219
  ])
220
220
  end
221
221
  end
222
222
 
223
- describe '#add_paragraph' do
224
- it 'adds a paragraph with text and formatting' do
223
+ describe "#add_paragraph" do
224
+ it "adds a paragraph with text and formatting" do
225
225
  cell = described_class.create
226
- para = cell.add_paragraph('Main text')
227
- para.add_text(' (', [Prosereflect::Mark::Bold.new])
228
- para.add_text('important', [Prosereflect::Mark::Bold.new, Prosereflect::Mark::Italic.new])
229
- para.add_text(')', [Prosereflect::Mark::Bold.new])
226
+ para = cell.add_paragraph("Main text")
227
+ para.add_text(" (", [Prosereflect::Mark::Bold.new])
228
+ para.add_text("important", [Prosereflect::Mark::Bold.new, Prosereflect::Mark::Italic.new])
229
+ para.add_text(")", [Prosereflect::Mark::Bold.new])
230
230
 
231
231
  expected = {
232
- 'type' => 'table_cell',
233
- 'content' => [{
234
- 'type' => 'paragraph',
235
- 'content' => [{
236
- 'type' => 'text',
237
- 'text' => 'Main text'
232
+ "type" => "table_cell",
233
+ "content" => [{
234
+ "type" => "paragraph",
235
+ "content" => [{
236
+ "type" => "text",
237
+ "text" => "Main text",
238
238
  }, {
239
- 'type' => 'text',
240
- 'text' => ' (',
241
- 'marks' => [{
242
- 'type' => 'bold'
243
- }]
239
+ "type" => "text",
240
+ "text" => " (",
241
+ "marks" => [{
242
+ "type" => "bold",
243
+ }],
244
244
  }, {
245
- 'type' => 'text',
246
- 'text' => 'important',
247
- 'marks' => [{
248
- 'type' => 'bold'
245
+ "type" => "text",
246
+ "text" => "important",
247
+ "marks" => [{
248
+ "type" => "bold",
249
249
  }, {
250
- 'type' => 'italic'
251
- }]
250
+ "type" => "italic",
251
+ }],
252
252
  }, {
253
- 'type' => 'text',
254
- 'text' => ')',
255
- 'marks' => [{
256
- 'type' => 'bold'
257
- }]
258
- }]
259
- }]
253
+ "type" => "text",
254
+ "text" => ")",
255
+ "marks" => [{
256
+ "type" => "bold",
257
+ }],
258
+ }],
259
+ }],
260
260
  }
261
261
 
262
262
  expect(cell.to_h).to eq(expected)
263
263
  end
264
264
 
265
- it 'adds multiple paragraphs with mixed content' do
265
+ it "adds multiple paragraphs with mixed content" do
266
266
  cell = described_class.create
267
267
 
268
268
  # First paragraph with hard break
269
- para = cell.add_paragraph('Title')
269
+ para = cell.add_paragraph("Title")
270
270
  para.add_hard_break
271
- para.add_text('Subtitle', [Prosereflect::Mark::Italic.new])
271
+ para.add_text("Subtitle", [Prosereflect::Mark::Italic.new])
272
272
 
273
273
  # Second paragraph with mixed formatting
274
274
  para = cell.add_paragraph
275
- para.add_text('Note: ', [Prosereflect::Mark::Bold.new])
276
- para.add_text('This is important')
275
+ para.add_text("Note: ", [Prosereflect::Mark::Bold.new])
276
+ para.add_text("This is important")
277
277
 
278
278
  expected = {
279
- 'type' => 'table_cell',
280
- 'content' => [{
281
- 'type' => 'paragraph',
282
- 'content' => [{
283
- 'type' => 'text',
284
- 'text' => 'Title'
279
+ "type" => "table_cell",
280
+ "content" => [{
281
+ "type" => "paragraph",
282
+ "content" => [{
283
+ "type" => "text",
284
+ "text" => "Title",
285
285
  }, {
286
- 'type' => 'hard_break'
286
+ "type" => "hard_break",
287
287
  }, {
288
- 'type' => 'text',
289
- 'text' => 'Subtitle',
290
- 'marks' => [{
291
- 'type' => 'italic'
292
- }]
293
- }]
288
+ "type" => "text",
289
+ "text" => "Subtitle",
290
+ "marks" => [{
291
+ "type" => "italic",
292
+ }],
293
+ }],
294
294
  }, {
295
- 'type' => 'paragraph',
296
- 'content' => [{
297
- 'type' => 'text',
298
- 'text' => 'Note: ',
299
- 'marks' => [{
300
- 'type' => 'bold'
301
- }]
295
+ "type" => "paragraph",
296
+ "content" => [{
297
+ "type" => "text",
298
+ "text" => "Note: ",
299
+ "marks" => [{
300
+ "type" => "bold",
301
+ }],
302
302
  }, {
303
- 'type' => 'text',
304
- 'text' => 'This is important'
305
- }]
306
- }]
303
+ "type" => "text",
304
+ "text" => "This is important",
305
+ }],
306
+ }],
307
307
  }
308
308
 
309
309
  expect(cell.to_h).to eq(expected)
@@ -311,15 +311,15 @@ RSpec.describe Prosereflect::TableCell do
311
311
  end
312
312
  end
313
313
 
314
- describe 'serialization' do
315
- it 'converts to hash representation' do
314
+ describe "serialization" do
315
+ it "converts to hash representation" do
316
316
  cell = described_class.new
317
- cell.add_paragraph('Test content')
317
+ cell.add_paragraph("Test content")
318
318
 
319
319
  hash = cell.to_h
320
- expect(hash['type']).to eq('table_cell')
321
- expect(hash['content'].size).to eq(1)
322
- expect(hash['content'][0]['type']).to eq('paragraph')
320
+ expect(hash["type"]).to eq("table_cell")
321
+ expect(hash["content"].size).to eq(1)
322
+ expect(hash["content"][0]["type"]).to eq("paragraph")
323
323
  end
324
324
  end
325
325
  end