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.
- checksums.yaml +4 -4
- data/.github/workflows/docs.yml +63 -0
- data/.github/workflows/links.yml +97 -0
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +19 -1
- data/.rubocop_todo.yml +119 -183
- data/CLAUDE.md +78 -0
- data/Gemfile +8 -4
- data/README.adoc +2 -0
- data/Rakefile +3 -3
- data/docs/Gemfile +10 -0
- data/docs/INDEX.adoc +45 -0
- data/docs/_advanced/index.adoc +15 -0
- data/docs/_advanced/schema.adoc +112 -0
- data/docs/_advanced/step-map.adoc +66 -0
- data/docs/_advanced/steps.adoc +88 -0
- data/docs/_advanced/test-builder.adoc +61 -0
- data/docs/_advanced/transform.adoc +92 -0
- data/docs/_config.yml +174 -0
- data/docs/_features/html-input.adoc +69 -0
- data/docs/_features/html-output.adoc +45 -0
- data/docs/_features/index.adoc +15 -0
- data/docs/_features/marks.adoc +86 -0
- data/docs/_features/node-types.adoc +124 -0
- data/docs/_features/user-mentions.adoc +47 -0
- data/docs/_guides/custom-nodes.adoc +107 -0
- data/docs/_guides/index.adoc +13 -0
- data/docs/_guides/round-trip-html.adoc +91 -0
- data/docs/_guides/serialization.adoc +109 -0
- data/docs/_pages/index.adoc +67 -0
- data/docs/_reference/document-api.adoc +49 -0
- data/docs/_reference/index.adoc +14 -0
- data/docs/_reference/node-api.adoc +79 -0
- data/docs/_reference/schema-api.adoc +95 -0
- data/docs/_reference/transform-api.adoc +77 -0
- data/docs/_understanding/document-model.adoc +65 -0
- data/docs/_understanding/fragment.adoc +52 -0
- data/docs/_understanding/index.adoc +14 -0
- data/docs/_understanding/resolved-position.adoc +53 -0
- data/docs/_understanding/slice.adoc +54 -0
- data/docs/lychee.toml +63 -0
- data/lib/prosereflect/attribute/base.rb +4 -6
- data/lib/prosereflect/attribute/bold.rb +2 -4
- data/lib/prosereflect/attribute/href.rb +1 -3
- data/lib/prosereflect/attribute/id.rb +7 -7
- data/lib/prosereflect/attribute.rb +4 -7
- data/lib/prosereflect/blockquote.rb +19 -11
- data/lib/prosereflect/bullet_list.rb +36 -29
- data/lib/prosereflect/code_block.rb +23 -27
- data/lib/prosereflect/code_block_wrapper.rb +12 -13
- data/lib/prosereflect/document.rb +14 -22
- data/lib/prosereflect/fragment.rb +249 -0
- data/lib/prosereflect/hard_break.rb +6 -6
- data/lib/prosereflect/heading.rb +14 -15
- data/lib/prosereflect/horizontal_rule.rb +23 -14
- data/lib/prosereflect/image.rb +32 -23
- data/lib/prosereflect/input/html.rb +179 -104
- data/lib/prosereflect/input.rb +7 -0
- data/lib/prosereflect/list_item.rb +11 -12
- data/lib/prosereflect/mark/base.rb +9 -11
- data/lib/prosereflect/mark/bold.rb +1 -3
- data/lib/prosereflect/mark/code.rb +1 -3
- data/lib/prosereflect/mark/italic.rb +1 -3
- data/lib/prosereflect/mark/link.rb +1 -3
- data/lib/prosereflect/mark/strike.rb +1 -3
- data/lib/prosereflect/mark/subscript.rb +1 -3
- data/lib/prosereflect/mark/superscript.rb +1 -3
- data/lib/prosereflect/mark/underline.rb +1 -3
- data/lib/prosereflect/mark.rb +9 -5
- data/lib/prosereflect/node.rb +171 -33
- data/lib/prosereflect/ordered_list.rb +17 -14
- data/lib/prosereflect/output/html.rb +279 -50
- data/lib/prosereflect/output.rb +7 -0
- data/lib/prosereflect/paragraph.rb +11 -13
- data/lib/prosereflect/parser.rb +56 -66
- data/lib/prosereflect/resolved_pos.rb +256 -0
- data/lib/prosereflect/schema/attribute.rb +57 -0
- data/lib/prosereflect/schema/content_match.rb +656 -0
- data/lib/prosereflect/schema/fragment.rb +166 -0
- data/lib/prosereflect/schema/mark.rb +121 -0
- data/lib/prosereflect/schema/mark_type.rb +130 -0
- data/lib/prosereflect/schema/node.rb +236 -0
- data/lib/prosereflect/schema/node_type.rb +274 -0
- data/lib/prosereflect/schema/schema_main.rb +190 -0
- data/lib/prosereflect/schema/spec.rb +92 -0
- data/lib/prosereflect/schema.rb +39 -0
- data/lib/prosereflect/table.rb +12 -13
- data/lib/prosereflect/table_cell.rb +13 -13
- data/lib/prosereflect/table_header.rb +17 -17
- data/lib/prosereflect/table_row.rb +12 -12
- data/lib/prosereflect/text.rb +35 -11
- data/lib/prosereflect/transform/attr_step.rb +157 -0
- data/lib/prosereflect/transform/insert_step.rb +115 -0
- data/lib/prosereflect/transform/mapping.rb +82 -0
- data/lib/prosereflect/transform/mark_step.rb +269 -0
- data/lib/prosereflect/transform/replace_around_step.rb +181 -0
- data/lib/prosereflect/transform/replace_step.rb +157 -0
- data/lib/prosereflect/transform/slice.rb +91 -0
- data/lib/prosereflect/transform/step.rb +89 -0
- data/lib/prosereflect/transform/step_map.rb +126 -0
- data/lib/prosereflect/transform/structure.rb +120 -0
- data/lib/prosereflect/transform/transform.rb +341 -0
- data/lib/prosereflect/transform.rb +26 -0
- data/lib/prosereflect/user.rb +15 -15
- data/lib/prosereflect/version.rb +1 -1
- data/lib/prosereflect.rb +30 -17
- data/prosereflect.gemspec +17 -16
- data/spec/fixtures/documents/formatted_text.yaml +14 -0
- data/spec/fixtures/documents/heading_paragraph.yaml +16 -0
- data/spec/fixtures/documents/lists_doc.yaml +32 -0
- data/spec/fixtures/documents/mixed_content.yaml +40 -0
- data/spec/fixtures/documents/nested_doc.yaml +20 -0
- data/spec/fixtures/documents/simple_doc.yaml +6 -0
- data/spec/fixtures/documents/table_doc.yaml +32 -0
- data/spec/fixtures/documents/transform_test.yaml +14 -0
- data/spec/fixtures/schema/custom_schema.rb +37 -0
- data/spec/fixtures/schema/test_schema.rb +46 -0
- data/spec/fixtures/test_builder/helpers.rb +212 -0
- data/spec/prosereflect/document_spec.rb +332 -330
- data/spec/prosereflect/fragment_spec.rb +273 -0
- data/spec/prosereflect/hard_break_spec.rb +125 -125
- data/spec/prosereflect/input/html_spec.rb +718 -522
- data/spec/prosereflect/node_spec.rb +311 -182
- data/spec/prosereflect/output/html_spec.rb +105 -105
- data/spec/prosereflect/output/whitespace_spec.rb +248 -0
- data/spec/prosereflect/paragraph_spec.rb +275 -274
- data/spec/prosereflect/parser/round_trip_spec.rb +472 -0
- data/spec/prosereflect/parser_spec.rb +185 -180
- data/spec/prosereflect/resolved_pos_spec.rb +74 -0
- data/spec/prosereflect/schema/conftest.rb +68 -0
- data/spec/prosereflect/schema/content_match_spec.rb +237 -0
- data/spec/prosereflect/schema/mark_spec.rb +274 -0
- data/spec/prosereflect/schema/mark_type_spec.rb +86 -0
- data/spec/prosereflect/schema/node_type_spec.rb +142 -0
- data/spec/prosereflect/schema/schema_spec.rb +194 -0
- data/spec/prosereflect/table_cell_spec.rb +183 -183
- data/spec/prosereflect/table_row_spec.rb +149 -149
- data/spec/prosereflect/table_spec.rb +320 -318
- data/spec/prosereflect/test_builder/marks_spec.rb +127 -0
- data/spec/prosereflect/text_spec.rb +133 -132
- data/spec/prosereflect/transform/equivalence_spec.rb +487 -0
- data/spec/prosereflect/transform/mapping_spec.rb +226 -0
- data/spec/prosereflect/transform/replace_spec.rb +832 -0
- data/spec/prosereflect/transform/replace_step_spec.rb +157 -0
- data/spec/prosereflect/transform/slice_spec.rb +48 -0
- data/spec/prosereflect/transform/step_map_spec.rb +70 -0
- data/spec/prosereflect/transform/step_spec.rb +211 -0
- data/spec/prosereflect/transform/structure_spec.rb +98 -0
- data/spec/prosereflect/transform/transform_spec.rb +238 -0
- data/spec/prosereflect/user_spec.rb +31 -28
- data/spec/prosereflect_spec.rb +28 -26
- data/spec/spec_helper.rb +7 -6
- data/spec/support/matchers.rb +6 -6
- data/spec/support/shared_examples.rb +49 -49
- metadata +96 -5
- data/spec/prosereflect/version_spec.rb +0 -11
|
@@ -1,309 +1,309 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "spec_helper"
|
|
4
4
|
|
|
5
5
|
RSpec.describe Prosereflect::TableCell do
|
|
6
|
-
describe
|
|
7
|
-
it
|
|
8
|
-
cell = described_class.new({
|
|
9
|
-
expect(cell.type).to eq(
|
|
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
|
|
14
|
-
it
|
|
13
|
+
describe ".create" do
|
|
14
|
+
it "creates an empty table cell" do
|
|
15
15
|
cell = described_class.create
|
|
16
16
|
|
|
17
17
|
expected = {
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
25
|
+
it "creates a table cell with attributes" do
|
|
26
26
|
cell = described_class.create(attrs: {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
"colspan" => 2,
|
|
28
|
+
"rowspan" => 1,
|
|
29
|
+
"background" => "#f5f5f5",
|
|
30
|
+
"align" => "center",
|
|
31
|
+
"valign" => "middle",
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
expected = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
"type" => "table_cell",
|
|
36
|
+
"attrs" => {
|
|
37
|
+
"colspan" => 2,
|
|
38
|
+
"rowspan" => 1,
|
|
39
|
+
"background" => "#f5f5f5",
|
|
40
|
+
"align" => "center",
|
|
41
|
+
"valign" => "middle",
|
|
42
42
|
},
|
|
43
|
-
|
|
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
|
|
51
|
-
it
|
|
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(
|
|
53
|
+
cell.add_paragraph("Simple text")
|
|
54
54
|
|
|
55
55
|
expected = {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
|
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(
|
|
74
|
-
para.add_text(
|
|
75
|
-
para.add_text(
|
|
76
|
-
para.add_text(
|
|
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(
|
|
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(
|
|
83
|
-
para.add_text(
|
|
84
|
-
para.add_text(
|
|
85
|
-
para.add_text(
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
"type" => "table_cell",
|
|
89
|
+
"content" => [{
|
|
90
|
+
"type" => "paragraph",
|
|
91
|
+
"content" => [{
|
|
92
|
+
"type" => "text",
|
|
93
|
+
"text" => "This is ",
|
|
94
94
|
}, {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}]
|
|
95
|
+
"type" => "text",
|
|
96
|
+
"text" => "bold",
|
|
97
|
+
"marks" => [{
|
|
98
|
+
"type" => "bold",
|
|
99
|
+
}],
|
|
100
100
|
}, {
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
"type" => "text",
|
|
102
|
+
"text" => " and ",
|
|
103
103
|
}, {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}]
|
|
104
|
+
"type" => "text",
|
|
105
|
+
"text" => "italic",
|
|
106
|
+
"marks" => [{
|
|
107
|
+
"type" => "italic",
|
|
108
|
+
}],
|
|
109
109
|
}, {
|
|
110
|
-
|
|
110
|
+
"type" => "hard_break",
|
|
111
111
|
}, {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}]
|
|
112
|
+
"type" => "text",
|
|
113
|
+
"text" => "with a line break",
|
|
114
|
+
}],
|
|
115
115
|
}, {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}]
|
|
116
|
+
"type" => "paragraph",
|
|
117
|
+
"content" => [{
|
|
118
|
+
"type" => "text",
|
|
119
|
+
"text" => "Status: ",
|
|
120
|
+
"marks" => [{
|
|
121
|
+
"type" => "bold",
|
|
122
|
+
}],
|
|
123
123
|
}, {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}]
|
|
124
|
+
"type" => "text",
|
|
125
|
+
"text" => "Done",
|
|
126
|
+
"marks" => [{
|
|
127
|
+
"type" => "strike",
|
|
128
|
+
}],
|
|
129
129
|
}, {
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
"type" => "text",
|
|
131
|
+
"text" => " → ",
|
|
132
132
|
}, {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
|
146
|
+
describe "cell operations" do
|
|
147
147
|
let(:cell) do
|
|
148
148
|
c = described_class.create
|
|
149
|
-
c.add_paragraph(
|
|
150
|
-
c.add_paragraph(
|
|
151
|
-
c.add_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
|
|
156
|
-
it
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
"First paragraph",
|
|
161
|
+
"Second paragraph",
|
|
162
|
+
"Third paragraph",
|
|
163
163
|
])
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
-
it
|
|
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
|
|
173
|
-
it
|
|
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
|
|
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
|
|
182
|
+
it "handles complex formatting and line breaks" do
|
|
183
183
|
cell = described_class.create
|
|
184
|
-
para = cell.add_paragraph(
|
|
184
|
+
para = cell.add_paragraph("Line 1")
|
|
185
185
|
para.add_hard_break
|
|
186
|
-
para.add_text(
|
|
186
|
+
para.add_text("Line 2", [Prosereflect::Mark::Bold.new])
|
|
187
187
|
para.add_hard_break
|
|
188
|
-
para.add_text(
|
|
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
|
|
195
|
-
it
|
|
194
|
+
describe "#lines" do
|
|
195
|
+
it "splits text content into lines" do
|
|
196
196
|
expect(cell.lines).to eq([
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
"First paragraph",
|
|
198
|
+
"Second paragraph",
|
|
199
|
+
"Third paragraph",
|
|
200
200
|
])
|
|
201
201
|
end
|
|
202
202
|
|
|
203
|
-
it
|
|
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
|
|
208
|
+
it "handles hard breaks within paragraphs" do
|
|
209
209
|
cell = described_class.create
|
|
210
|
-
para = cell.add_paragraph(
|
|
210
|
+
para = cell.add_paragraph("First line")
|
|
211
211
|
para.add_hard_break
|
|
212
|
-
para.add_text(
|
|
213
|
-
cell.add_paragraph(
|
|
212
|
+
para.add_text("Second line")
|
|
213
|
+
cell.add_paragraph("Third line")
|
|
214
214
|
|
|
215
215
|
expect(cell.lines).to eq([
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
"First line",
|
|
217
|
+
"Second line",
|
|
218
|
+
"Third line",
|
|
219
219
|
])
|
|
220
220
|
end
|
|
221
221
|
end
|
|
222
222
|
|
|
223
|
-
describe
|
|
224
|
-
it
|
|
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(
|
|
227
|
-
para.add_text(
|
|
228
|
-
para.add_text(
|
|
229
|
-
para.add_text(
|
|
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
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
232
|
+
"type" => "table_cell",
|
|
233
|
+
"content" => [{
|
|
234
|
+
"type" => "paragraph",
|
|
235
|
+
"content" => [{
|
|
236
|
+
"type" => "text",
|
|
237
|
+
"text" => "Main text",
|
|
238
238
|
}, {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}]
|
|
239
|
+
"type" => "text",
|
|
240
|
+
"text" => " (",
|
|
241
|
+
"marks" => [{
|
|
242
|
+
"type" => "bold",
|
|
243
|
+
}],
|
|
244
244
|
}, {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
"type" => "text",
|
|
246
|
+
"text" => "important",
|
|
247
|
+
"marks" => [{
|
|
248
|
+
"type" => "bold",
|
|
249
249
|
}, {
|
|
250
|
-
|
|
251
|
-
}]
|
|
250
|
+
"type" => "italic",
|
|
251
|
+
}],
|
|
252
252
|
}, {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
|
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(
|
|
269
|
+
para = cell.add_paragraph("Title")
|
|
270
270
|
para.add_hard_break
|
|
271
|
-
para.add_text(
|
|
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(
|
|
276
|
-
para.add_text(
|
|
275
|
+
para.add_text("Note: ", [Prosereflect::Mark::Bold.new])
|
|
276
|
+
para.add_text("This is important")
|
|
277
277
|
|
|
278
278
|
expected = {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
279
|
+
"type" => "table_cell",
|
|
280
|
+
"content" => [{
|
|
281
|
+
"type" => "paragraph",
|
|
282
|
+
"content" => [{
|
|
283
|
+
"type" => "text",
|
|
284
|
+
"text" => "Title",
|
|
285
285
|
}, {
|
|
286
|
-
|
|
286
|
+
"type" => "hard_break",
|
|
287
287
|
}, {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}]
|
|
293
|
-
}]
|
|
288
|
+
"type" => "text",
|
|
289
|
+
"text" => "Subtitle",
|
|
290
|
+
"marks" => [{
|
|
291
|
+
"type" => "italic",
|
|
292
|
+
}],
|
|
293
|
+
}],
|
|
294
294
|
}, {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}]
|
|
295
|
+
"type" => "paragraph",
|
|
296
|
+
"content" => [{
|
|
297
|
+
"type" => "text",
|
|
298
|
+
"text" => "Note: ",
|
|
299
|
+
"marks" => [{
|
|
300
|
+
"type" => "bold",
|
|
301
|
+
}],
|
|
302
302
|
}, {
|
|
303
|
-
|
|
304
|
-
|
|
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
|
|
315
|
-
it
|
|
314
|
+
describe "serialization" do
|
|
315
|
+
it "converts to hash representation" do
|
|
316
316
|
cell = described_class.new
|
|
317
|
-
cell.add_paragraph(
|
|
317
|
+
cell.add_paragraph("Test content")
|
|
318
318
|
|
|
319
319
|
hash = cell.to_h
|
|
320
|
-
expect(hash[
|
|
321
|
-
expect(hash[
|
|
322
|
-
expect(hash[
|
|
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
|