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
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe Prosereflect::Transform::Mapping do
|
|
6
|
+
let(:step_map) { Prosereflect::Transform::StepMap.new([[0, 5, 0, 5]]) }
|
|
7
|
+
|
|
8
|
+
describe "creation" do
|
|
9
|
+
it "creates empty mapping" do
|
|
10
|
+
mapping = described_class.new
|
|
11
|
+
expect(mapping.to_a).to eq([])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "creates mapping with step maps" do
|
|
15
|
+
mapping = described_class.new(maps: [step_map])
|
|
16
|
+
expect(mapping.to_a.length).to eq(1)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "add_map" do
|
|
21
|
+
it "adds step map to end" do
|
|
22
|
+
mapping = described_class.new
|
|
23
|
+
mapping.add_map(step_map)
|
|
24
|
+
expect(mapping.to_a.length).to eq(1)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "adds step map at specific index" do
|
|
28
|
+
mapping = described_class.new(maps: [step_map])
|
|
29
|
+
new_map = Prosereflect::Transform::StepMap.new([[10, 15, 10, 15]])
|
|
30
|
+
mapping.add_map(new_map, 0)
|
|
31
|
+
expect(mapping.to_a.length).to eq(2)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "map" do
|
|
36
|
+
it "maps position through empty mapping returns same position" do
|
|
37
|
+
mapping = described_class.new
|
|
38
|
+
expect(mapping.map(5)).to eq(5)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "maps position through single step map" do
|
|
42
|
+
# StepMap [[0, 5, 0, 5]] means: old 0-5 maps to new 0-5 (no change)
|
|
43
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 5, 0, 5]])
|
|
44
|
+
mapping = described_class.new(maps: [step_map])
|
|
45
|
+
expect(mapping.map(3)).to eq(3)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "maps position through multiple step maps" do
|
|
49
|
+
# First step: positions 0-5 stay at 0-5
|
|
50
|
+
# Second step: positions 5-10 stay at 5-5 (5 chars inserted)
|
|
51
|
+
map1 = Prosereflect::Transform::StepMap.new([[0, 5, 0, 5]])
|
|
52
|
+
map2 = Prosereflect::Transform::StepMap.new([[5, 10, 5, 5]])
|
|
53
|
+
mapping = described_class.new(maps: [map1, map2])
|
|
54
|
+
expect(mapping.map(3)).to eq(3)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "handles deletion step map" do
|
|
58
|
+
# StepMap [[0, 3, 0, 0]] means: old 0-3 maps to new 0-0 (3 deleted)
|
|
59
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 3, 0, 0]])
|
|
60
|
+
mapping = described_class.new(maps: [step_map])
|
|
61
|
+
# Position 5 (after deletion) should be offset by -3
|
|
62
|
+
expect(mapping.map(5)).to eq(2)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe "map_result" do
|
|
67
|
+
it "returns pos and deleted status for position not deleted" do
|
|
68
|
+
# StepMap [[0, 2, 0, 2]] deletes 0-1, position 5 is after range
|
|
69
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 2, 0, 2]])
|
|
70
|
+
mapping = described_class.new(maps: [step_map])
|
|
71
|
+
result = mapping.map_result(5)
|
|
72
|
+
expect(result[:pos]).to eq(5)
|
|
73
|
+
expect(result[:deleted]).to be false
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "returns deleted true for position in deleted range" do
|
|
77
|
+
# StepMap [[0, 3, 0, 0]] means: old 0-3 maps to new 0-0 (3 deleted)
|
|
78
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 3, 0, 0]])
|
|
79
|
+
mapping = described_class.new(maps: [step_map])
|
|
80
|
+
result = mapping.map_result(1)
|
|
81
|
+
expect(result[:deleted]).to be true
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "map_deletes" do
|
|
86
|
+
it "returns false when position not deleted" do
|
|
87
|
+
mapping = described_class.new(maps: [step_map])
|
|
88
|
+
expect(mapping.map_deletes(10)).to be false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "returns true when position deleted" do
|
|
92
|
+
# StepMap [[0, 5, 0, 0]] is a deletion of 0-5
|
|
93
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 5, 0, 0]])
|
|
94
|
+
mapping = described_class.new(maps: [step_map])
|
|
95
|
+
expect(mapping.map_deletes(2)).to be true
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "returns false for position after deleted range" do
|
|
99
|
+
# StepMap [[0, 3, 0, 0]] deletes 0-3
|
|
100
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 3, 0, 0]])
|
|
101
|
+
mapping = described_class.new(maps: [step_map])
|
|
102
|
+
# Position 5 is after the deleted range
|
|
103
|
+
expect(mapping.map_deletes(5)).to be false
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "to_a" do
|
|
108
|
+
it "returns array of step maps" do
|
|
109
|
+
mapping = described_class.new(maps: [step_map])
|
|
110
|
+
expect(mapping.to_a).to eq([step_map])
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe "from_step_map" do
|
|
115
|
+
it "creates mapping from single step map" do
|
|
116
|
+
mapping = described_class.from_step_map(step_map)
|
|
117
|
+
expect(mapping.to_a).to eq([step_map])
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context "with StepMap" do
|
|
122
|
+
describe "creation" do
|
|
123
|
+
it "creates empty step map" do
|
|
124
|
+
step_map = Prosereflect::Transform::StepMap.new
|
|
125
|
+
expect(step_map.ranges).to eq([])
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "creates step map with ranges" do
|
|
129
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 5, 0, 5]])
|
|
130
|
+
expect(step_map.ranges).to eq([[0, 5, 0, 5]])
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
describe ".empty" do
|
|
135
|
+
it "returns empty step map" do
|
|
136
|
+
step_map = Prosereflect::Transform::StepMap.empty
|
|
137
|
+
expect(step_map.ranges).to eq([])
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe ".delete" do
|
|
142
|
+
it "creates step map for deletion" do
|
|
143
|
+
step_map = Prosereflect::Transform::StepMap.delete(2, 5)
|
|
144
|
+
# [[2, 5, 2, 2]] - from 2 to 5 deleted, maps to position 2
|
|
145
|
+
expect(step_map.ranges).to eq([[2, 5, 2, 2]])
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
describe ".replace" do
|
|
150
|
+
it "creates step map for replacement" do
|
|
151
|
+
step_map = Prosereflect::Transform::StepMap.replace(0, 3, 0, 5)
|
|
152
|
+
# [[0, 3, 0, 5]] - old 0-3 replaced with new 0-5
|
|
153
|
+
expect(step_map.ranges).to eq([[0, 3, 0, 5]])
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
describe "map" do
|
|
158
|
+
it "maps position before any range unchanged" do
|
|
159
|
+
step_map = Prosereflect::Transform::StepMap.new([[5, 10, 5, 10]])
|
|
160
|
+
expect(step_map.map(3)).to eq(3)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it "maps position within range" do
|
|
164
|
+
step_map = Prosereflect::Transform::StepMap.new([[2, 5, 2, 8]])
|
|
165
|
+
# Position 3 within old 2-5 maps to 2 + (3-2) = 3
|
|
166
|
+
expect(step_map.map(3)).to eq(3)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "maps position after range with offset" do
|
|
170
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 3, 0, 0]])
|
|
171
|
+
# Position 5 is after deleted range 0-3
|
|
172
|
+
# offset = (0 - 3) = -3
|
|
173
|
+
expect(step_map.map(5)).to eq(2)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
describe "map_result" do
|
|
178
|
+
it "returns result with deleted false when not deleted" do
|
|
179
|
+
# StepMap [[0, 2, 0, 2]] deletes 0-1, position 5 is not in range
|
|
180
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 2, 0, 2]])
|
|
181
|
+
result = step_map.map_result(5)
|
|
182
|
+
expect(result.deleted).to be false
|
|
183
|
+
expect(result.pos).to eq(5)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it "returns result with deleted true when in range" do
|
|
187
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 5, 0, 0]])
|
|
188
|
+
result = step_map.map_result(2)
|
|
189
|
+
expect(result.deleted).to be true
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
describe "deleted?" do
|
|
194
|
+
it "returns true for position in deleted range" do
|
|
195
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 5, 0, 0]])
|
|
196
|
+
expect(step_map.deleted?(2)).to be true
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "returns false for position after range" do
|
|
200
|
+
step_map = Prosereflect::Transform::StepMap.new([[0, 5, 0, 0]])
|
|
201
|
+
expect(step_map.deleted?(10)).to be false
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "returns false for position before range" do
|
|
205
|
+
step_map = Prosereflect::Transform::StepMap.new([[5, 10, 5, 10]])
|
|
206
|
+
expect(step_map.deleted?(2)).to be false
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
describe "add_map" do
|
|
211
|
+
it "returns other map when self is empty" do
|
|
212
|
+
empty = Prosereflect::Transform::StepMap.new
|
|
213
|
+
other = Prosereflect::Transform::StepMap.new([[0, 5, 0, 5]])
|
|
214
|
+
result = empty.add_map(other)
|
|
215
|
+
expect(result.ranges).to eq([[0, 5, 0, 5]])
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "returns self when other is empty" do
|
|
219
|
+
map = Prosereflect::Transform::StepMap.new([[0, 5, 0, 5]])
|
|
220
|
+
empty = Prosereflect::Transform::StepMap.new
|
|
221
|
+
result = map.add_map(empty)
|
|
222
|
+
expect(result.ranges).to eq([[0, 5, 0, 5]])
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|