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.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.rubocop.yml +19 -1
- data/.rubocop_todo.yml +141 -191
- data/CLAUDE.md +78 -0
- data/Gemfile +8 -4
- data/Rakefile +3 -3
- 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 +10 -11
- data/lib/prosereflect/bullet_list.rb +16 -15
- data/lib/prosereflect/code_block.rb +26 -26
- data/lib/prosereflect/code_block_wrapper.rb +12 -13
- data/lib/prosereflect/document.rb +14 -22
- data/lib/prosereflect/hard_break.rb +6 -6
- data/lib/prosereflect/heading.rb +14 -15
- data/lib/prosereflect/horizontal_rule.rb +14 -14
- data/lib/prosereflect/image.rb +23 -23
- data/lib/prosereflect/input/html.rb +83 -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 +31 -31
- data/lib/prosereflect/ordered_list.rb +15 -14
- data/lib/prosereflect/output/html.rb +52 -50
- data/lib/prosereflect/output.rb +7 -0
- data/lib/prosereflect/paragraph.rb +11 -13
- data/lib/prosereflect/parser.rb +47 -66
- 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 +11 -11
- data/lib/prosereflect/user.rb +15 -15
- data/lib/prosereflect/version.rb +1 -1
- data/lib/prosereflect.rb +27 -17
- data/prosereflect.gemspec +17 -16
- data/spec/prosereflect/document_spec.rb +332 -330
- data/spec/prosereflect/hard_break_spec.rb +125 -125
- data/spec/prosereflect/input/html_spec.rb +522 -522
- data/spec/prosereflect/node_spec.rb +183 -182
- data/spec/prosereflect/output/html_spec.rb +105 -105
- data/spec/prosereflect/paragraph_spec.rb +275 -274
- data/spec/prosereflect/parser_spec.rb +185 -180
- 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/text_spec.rb +133 -132
- data/spec/prosereflect/user_spec.rb +31 -28
- data/spec/prosereflect_spec.rb +28 -26
- data/spec/spec_helper.rb +6 -6
- data/spec/support/matchers.rb +6 -6
- data/spec/support/shared_examples.rb +49 -49
- metadata +8 -5
- data/spec/prosereflect/version_spec.rb +0 -11
|
@@ -1,247 +1,247 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "spec_helper"
|
|
4
4
|
|
|
5
5
|
RSpec.describe Prosereflect::HardBreak do
|
|
6
|
-
describe
|
|
7
|
-
it
|
|
8
|
-
break_node = described_class.new({
|
|
9
|
-
expect(break_node.type).to eq(
|
|
6
|
+
describe "initialization" do
|
|
7
|
+
it "initializes as a hard_break node" do
|
|
8
|
+
break_node = described_class.new({ "type" => "hard_break" })
|
|
9
|
+
expect(break_node.type).to eq("hard_break")
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
describe
|
|
14
|
-
it
|
|
13
|
+
describe ".create" do
|
|
14
|
+
it "creates a simple hard break" do
|
|
15
15
|
break_node = described_class.create
|
|
16
16
|
|
|
17
17
|
expected = {
|
|
18
|
-
|
|
18
|
+
"type" => "hard_break",
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
expect(break_node.to_h).to eq(expected)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
it
|
|
24
|
+
it "creates a hard break with a single mark" do
|
|
25
25
|
break_node = described_class.create
|
|
26
|
-
break_node.marks = [{
|
|
26
|
+
break_node.marks = [{ "type" => "bold" }]
|
|
27
27
|
|
|
28
28
|
expected = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}]
|
|
29
|
+
"type" => "hard_break",
|
|
30
|
+
"marks" => [{
|
|
31
|
+
"type" => "bold",
|
|
32
|
+
}],
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
expect(break_node.to_h).to eq(expected)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
it
|
|
38
|
+
it "creates a hard break with multiple marks" do
|
|
39
39
|
break_node = described_class.create
|
|
40
40
|
break_node.marks = [
|
|
41
|
-
{
|
|
42
|
-
{
|
|
43
|
-
{
|
|
41
|
+
{ "type" => "bold" },
|
|
42
|
+
{ "type" => "italic" },
|
|
43
|
+
{ "type" => "strike" },
|
|
44
44
|
]
|
|
45
45
|
|
|
46
46
|
expected = {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
"type" => "hard_break",
|
|
48
|
+
"marks" => [{
|
|
49
|
+
"type" => "bold",
|
|
50
50
|
}, {
|
|
51
|
-
|
|
51
|
+
"type" => "italic",
|
|
52
52
|
}, {
|
|
53
|
-
|
|
54
|
-
}]
|
|
53
|
+
"type" => "strike",
|
|
54
|
+
}],
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
expect(break_node.to_h).to eq(expected)
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
describe
|
|
62
|
-
it
|
|
61
|
+
describe "in document context" do
|
|
62
|
+
it "works in a paragraph with mixed content" do
|
|
63
63
|
paragraph = Prosereflect::Paragraph.new
|
|
64
|
-
paragraph.add_text(
|
|
64
|
+
paragraph.add_text("First line")
|
|
65
65
|
paragraph.add_hard_break
|
|
66
|
-
paragraph.add_text(
|
|
67
|
-
paragraph.add_text(
|
|
66
|
+
paragraph.add_text("Second line with ")
|
|
67
|
+
paragraph.add_text("bold", [Prosereflect::Mark::Bold.new])
|
|
68
68
|
paragraph.add_hard_break
|
|
69
|
-
paragraph.add_text(
|
|
69
|
+
paragraph.add_text("Third line")
|
|
70
70
|
|
|
71
71
|
expected = {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
"type" => "paragraph",
|
|
73
|
+
"content" => [{
|
|
74
|
+
"type" => "text",
|
|
75
|
+
"text" => "First line",
|
|
76
76
|
}, {
|
|
77
|
-
|
|
77
|
+
"type" => "hard_break",
|
|
78
78
|
}, {
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
"type" => "text",
|
|
80
|
+
"text" => "Second line with ",
|
|
81
81
|
}, {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}]
|
|
82
|
+
"type" => "text",
|
|
83
|
+
"text" => "bold",
|
|
84
|
+
"marks" => [{
|
|
85
|
+
"type" => "bold",
|
|
86
|
+
}],
|
|
87
87
|
}, {
|
|
88
|
-
|
|
88
|
+
"type" => "hard_break",
|
|
89
89
|
}, {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}]
|
|
90
|
+
"type" => "text",
|
|
91
|
+
"text" => "Third line",
|
|
92
|
+
}],
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
expect(paragraph.to_h).to eq(expected)
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
it
|
|
98
|
+
it "works in a list item with multiple breaks" do
|
|
99
99
|
list = Prosereflect::BulletList.new
|
|
100
|
-
item = list.add_item(
|
|
101
|
-
item.add_hard_break([{
|
|
102
|
-
item.add_text(
|
|
100
|
+
item = list.add_item("First part")
|
|
101
|
+
item.add_hard_break([{ "type" => "strike" }])
|
|
102
|
+
item.add_text("Second part")
|
|
103
103
|
item.add_hard_break
|
|
104
|
-
item.add_text(
|
|
104
|
+
item.add_text("Third part")
|
|
105
105
|
|
|
106
106
|
expected = {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
"type" => "bullet_list",
|
|
108
|
+
"attrs" => {
|
|
109
|
+
"bullet_style" => nil,
|
|
110
110
|
},
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
"content" => [{
|
|
112
|
+
"type" => "list_item",
|
|
113
|
+
"content" => [{
|
|
114
|
+
"type" => "paragraph",
|
|
115
|
+
"content" => [{
|
|
116
|
+
"type" => "text",
|
|
117
|
+
"text" => "First part",
|
|
118
118
|
}, {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}]
|
|
119
|
+
"type" => "hard_break",
|
|
120
|
+
"marks" => [{
|
|
121
|
+
"type" => "strike",
|
|
122
|
+
}],
|
|
123
123
|
}, {
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
"type" => "text",
|
|
125
|
+
"text" => "Second part",
|
|
126
126
|
}, {
|
|
127
|
-
|
|
127
|
+
"type" => "hard_break",
|
|
128
128
|
}, {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}]
|
|
132
|
-
}]
|
|
133
|
-
}]
|
|
129
|
+
"type" => "text",
|
|
130
|
+
"text" => "Third part",
|
|
131
|
+
}],
|
|
132
|
+
}],
|
|
133
|
+
}],
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
expect(list.to_h).to eq(expected)
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
-
it
|
|
139
|
+
it "works in a table cell with multiple paragraphs" do
|
|
140
140
|
cell = Prosereflect::TableCell.new
|
|
141
|
-
para1 = cell.add_paragraph(
|
|
141
|
+
para1 = cell.add_paragraph("First paragraph")
|
|
142
142
|
para1.add_hard_break
|
|
143
|
-
para1.add_text(
|
|
143
|
+
para1.add_text("continues here")
|
|
144
144
|
|
|
145
|
-
para2 = cell.add_paragraph(
|
|
145
|
+
para2 = cell.add_paragraph("Second paragraph")
|
|
146
146
|
para2.add_hard_break([Prosereflect::Mark::Italic.new])
|
|
147
|
-
para2.add_text(
|
|
147
|
+
para2.add_text("with style")
|
|
148
148
|
|
|
149
149
|
expected = {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
150
|
+
"type" => "table_cell",
|
|
151
|
+
"content" => [{
|
|
152
|
+
"type" => "paragraph",
|
|
153
|
+
"content" => [{
|
|
154
|
+
"type" => "text",
|
|
155
|
+
"text" => "First paragraph",
|
|
156
156
|
}, {
|
|
157
|
-
|
|
157
|
+
"type" => "hard_break",
|
|
158
158
|
}, {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}]
|
|
159
|
+
"type" => "text",
|
|
160
|
+
"text" => "continues here",
|
|
161
|
+
}],
|
|
162
162
|
}, {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
"type" => "paragraph",
|
|
164
|
+
"content" => [{
|
|
165
|
+
"type" => "text",
|
|
166
|
+
"text" => "Second paragraph",
|
|
167
167
|
}, {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}]
|
|
168
|
+
"type" => "hard_break",
|
|
169
|
+
"marks" => [{
|
|
170
|
+
"type" => "italic",
|
|
171
|
+
}],
|
|
172
172
|
}, {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}]
|
|
176
|
-
}]
|
|
173
|
+
"type" => "text",
|
|
174
|
+
"text" => "with style",
|
|
175
|
+
}],
|
|
176
|
+
}],
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
expect(cell.to_h).to eq(expected)
|
|
180
180
|
end
|
|
181
181
|
end
|
|
182
182
|
|
|
183
|
-
describe
|
|
184
|
-
it
|
|
183
|
+
describe "#text_content" do
|
|
184
|
+
it "returns a newline character" do
|
|
185
185
|
break_node = described_class.new
|
|
186
186
|
expect(break_node.text_content).to eq("\n")
|
|
187
187
|
end
|
|
188
188
|
|
|
189
|
-
it
|
|
189
|
+
it "returns a newline character regardless of marks" do
|
|
190
190
|
break_node = described_class.create(marks: [
|
|
191
191
|
Prosereflect::Mark::Bold.new,
|
|
192
|
-
Prosereflect::Mark::Italic.new
|
|
192
|
+
Prosereflect::Mark::Italic.new,
|
|
193
193
|
])
|
|
194
194
|
expect(break_node.text_content).to eq("\n")
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
it
|
|
197
|
+
it "properly formats text in a paragraph with multiple breaks" do
|
|
198
198
|
paragraph = Prosereflect::Paragraph.new
|
|
199
|
-
paragraph.add_text(
|
|
199
|
+
paragraph.add_text("Line 1")
|
|
200
200
|
paragraph.add_hard_break
|
|
201
|
-
paragraph.add_text(
|
|
201
|
+
paragraph.add_text("Line 2")
|
|
202
202
|
paragraph.add_hard_break
|
|
203
|
-
paragraph.add_text(
|
|
203
|
+
paragraph.add_text("Line 3")
|
|
204
204
|
|
|
205
205
|
expect(paragraph.text_content).to eq("Line 1\nLine 2\nLine 3")
|
|
206
206
|
end
|
|
207
207
|
end
|
|
208
208
|
|
|
209
|
-
describe
|
|
210
|
-
it
|
|
209
|
+
describe "serialization" do
|
|
210
|
+
it "preserves mark order in serialization" do
|
|
211
211
|
break_node = described_class.create
|
|
212
212
|
break_node.marks = [
|
|
213
|
-
{
|
|
214
|
-
{
|
|
215
|
-
{
|
|
216
|
-
{
|
|
213
|
+
{ "type" => "bold" },
|
|
214
|
+
{ "type" => "italic" },
|
|
215
|
+
{ "type" => "strike" },
|
|
216
|
+
{ "type" => "underline" },
|
|
217
217
|
]
|
|
218
218
|
|
|
219
219
|
expected = {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
"type" => "hard_break",
|
|
221
|
+
"marks" => [{
|
|
222
|
+
"type" => "bold",
|
|
223
223
|
}, {
|
|
224
|
-
|
|
224
|
+
"type" => "italic",
|
|
225
225
|
}, {
|
|
226
|
-
|
|
226
|
+
"type" => "strike",
|
|
227
227
|
}, {
|
|
228
|
-
|
|
229
|
-
}]
|
|
228
|
+
"type" => "underline",
|
|
229
|
+
}],
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
expect(break_node.to_h).to eq(expected)
|
|
233
233
|
end
|
|
234
234
|
|
|
235
|
-
it
|
|
235
|
+
it "handles empty marks array" do
|
|
236
236
|
break_node = described_class.create
|
|
237
237
|
break_node.marks = []
|
|
238
|
-
expect(break_node.to_h).to eq({
|
|
238
|
+
expect(break_node.to_h).to eq({ "type" => "hard_break" })
|
|
239
239
|
end
|
|
240
240
|
|
|
241
|
-
it
|
|
241
|
+
it "excludes marks when nil" do
|
|
242
242
|
break_node = described_class.create
|
|
243
243
|
break_node.marks = nil
|
|
244
|
-
expect(break_node.to_h).to eq({
|
|
244
|
+
expect(break_node.to_h).to eq({ "type" => "hard_break" })
|
|
245
245
|
end
|
|
246
246
|
end
|
|
247
247
|
end
|