prosereflect 0.2.0 → 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 (110) 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/.gitignore +4 -0
  5. data/.rubocop_todo.yml +61 -75
  6. data/README.adoc +2 -0
  7. data/docs/Gemfile +10 -0
  8. data/docs/INDEX.adoc +45 -0
  9. data/docs/_advanced/index.adoc +15 -0
  10. data/docs/_advanced/schema.adoc +112 -0
  11. data/docs/_advanced/step-map.adoc +66 -0
  12. data/docs/_advanced/steps.adoc +88 -0
  13. data/docs/_advanced/test-builder.adoc +61 -0
  14. data/docs/_advanced/transform.adoc +92 -0
  15. data/docs/_config.yml +174 -0
  16. data/docs/_features/html-input.adoc +69 -0
  17. data/docs/_features/html-output.adoc +45 -0
  18. data/docs/_features/index.adoc +15 -0
  19. data/docs/_features/marks.adoc +86 -0
  20. data/docs/_features/node-types.adoc +124 -0
  21. data/docs/_features/user-mentions.adoc +47 -0
  22. data/docs/_guides/custom-nodes.adoc +107 -0
  23. data/docs/_guides/index.adoc +13 -0
  24. data/docs/_guides/round-trip-html.adoc +91 -0
  25. data/docs/_guides/serialization.adoc +109 -0
  26. data/docs/_pages/index.adoc +67 -0
  27. data/docs/_reference/document-api.adoc +49 -0
  28. data/docs/_reference/index.adoc +14 -0
  29. data/docs/_reference/node-api.adoc +79 -0
  30. data/docs/_reference/schema-api.adoc +95 -0
  31. data/docs/_reference/transform-api.adoc +77 -0
  32. data/docs/_understanding/document-model.adoc +65 -0
  33. data/docs/_understanding/fragment.adoc +52 -0
  34. data/docs/_understanding/index.adoc +14 -0
  35. data/docs/_understanding/resolved-position.adoc +53 -0
  36. data/docs/_understanding/slice.adoc +54 -0
  37. data/docs/lychee.toml +63 -0
  38. data/lib/prosereflect/blockquote.rb +9 -0
  39. data/lib/prosereflect/bullet_list.rb +25 -19
  40. data/lib/prosereflect/code_block.rb +1 -5
  41. data/lib/prosereflect/fragment.rb +249 -0
  42. data/lib/prosereflect/horizontal_rule.rb +9 -0
  43. data/lib/prosereflect/image.rb +9 -0
  44. data/lib/prosereflect/input/html.rb +96 -0
  45. data/lib/prosereflect/node.rb +141 -3
  46. data/lib/prosereflect/ordered_list.rb +2 -0
  47. data/lib/prosereflect/output/html.rb +227 -0
  48. data/lib/prosereflect/parser.rb +9 -0
  49. data/lib/prosereflect/resolved_pos.rb +256 -0
  50. data/lib/prosereflect/schema/attribute.rb +57 -0
  51. data/lib/prosereflect/schema/content_match.rb +656 -0
  52. data/lib/prosereflect/schema/fragment.rb +166 -0
  53. data/lib/prosereflect/schema/mark.rb +121 -0
  54. data/lib/prosereflect/schema/mark_type.rb +130 -0
  55. data/lib/prosereflect/schema/node.rb +236 -0
  56. data/lib/prosereflect/schema/node_type.rb +274 -0
  57. data/lib/prosereflect/schema/schema_main.rb +190 -0
  58. data/lib/prosereflect/schema/spec.rb +92 -0
  59. data/lib/prosereflect/schema.rb +39 -0
  60. data/lib/prosereflect/text.rb +24 -0
  61. data/lib/prosereflect/transform/attr_step.rb +157 -0
  62. data/lib/prosereflect/transform/insert_step.rb +115 -0
  63. data/lib/prosereflect/transform/mapping.rb +82 -0
  64. data/lib/prosereflect/transform/mark_step.rb +269 -0
  65. data/lib/prosereflect/transform/replace_around_step.rb +181 -0
  66. data/lib/prosereflect/transform/replace_step.rb +157 -0
  67. data/lib/prosereflect/transform/slice.rb +91 -0
  68. data/lib/prosereflect/transform/step.rb +89 -0
  69. data/lib/prosereflect/transform/step_map.rb +126 -0
  70. data/lib/prosereflect/transform/structure.rb +120 -0
  71. data/lib/prosereflect/transform/transform.rb +341 -0
  72. data/lib/prosereflect/transform.rb +26 -0
  73. data/lib/prosereflect/version.rb +1 -1
  74. data/lib/prosereflect.rb +3 -0
  75. data/spec/fixtures/documents/formatted_text.yaml +14 -0
  76. data/spec/fixtures/documents/heading_paragraph.yaml +16 -0
  77. data/spec/fixtures/documents/lists_doc.yaml +32 -0
  78. data/spec/fixtures/documents/mixed_content.yaml +40 -0
  79. data/spec/fixtures/documents/nested_doc.yaml +20 -0
  80. data/spec/fixtures/documents/simple_doc.yaml +6 -0
  81. data/spec/fixtures/documents/table_doc.yaml +32 -0
  82. data/spec/fixtures/documents/transform_test.yaml +14 -0
  83. data/spec/fixtures/schema/custom_schema.rb +37 -0
  84. data/spec/fixtures/schema/test_schema.rb +46 -0
  85. data/spec/fixtures/test_builder/helpers.rb +212 -0
  86. data/spec/prosereflect/document_spec.rb +1 -1
  87. data/spec/prosereflect/fragment_spec.rb +273 -0
  88. data/spec/prosereflect/input/html_spec.rb +197 -1
  89. data/spec/prosereflect/node_spec.rb +128 -0
  90. data/spec/prosereflect/output/whitespace_spec.rb +248 -0
  91. data/spec/prosereflect/parser/round_trip_spec.rb +472 -0
  92. data/spec/prosereflect/resolved_pos_spec.rb +74 -0
  93. data/spec/prosereflect/schema/conftest.rb +68 -0
  94. data/spec/prosereflect/schema/content_match_spec.rb +237 -0
  95. data/spec/prosereflect/schema/mark_spec.rb +274 -0
  96. data/spec/prosereflect/schema/mark_type_spec.rb +86 -0
  97. data/spec/prosereflect/schema/node_type_spec.rb +142 -0
  98. data/spec/prosereflect/schema/schema_spec.rb +194 -0
  99. data/spec/prosereflect/test_builder/marks_spec.rb +127 -0
  100. data/spec/prosereflect/transform/equivalence_spec.rb +487 -0
  101. data/spec/prosereflect/transform/mapping_spec.rb +226 -0
  102. data/spec/prosereflect/transform/replace_spec.rb +832 -0
  103. data/spec/prosereflect/transform/replace_step_spec.rb +157 -0
  104. data/spec/prosereflect/transform/slice_spec.rb +48 -0
  105. data/spec/prosereflect/transform/step_map_spec.rb +70 -0
  106. data/spec/prosereflect/transform/step_spec.rb +211 -0
  107. data/spec/prosereflect/transform/structure_spec.rb +98 -0
  108. data/spec/prosereflect/transform/transform_spec.rb +238 -0
  109. data/spec/spec_helper.rb +1 -0
  110. metadata +90 -2
@@ -0,0 +1,238 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Prosereflect::Transform::Transform do
6
+ let(:doc) { Prosereflect::Document.new }
7
+
8
+ describe "creation" do
9
+ it "creates transform with document" do
10
+ transform = described_class.new(doc)
11
+ expect(transform.doc).to eq(doc)
12
+ end
13
+
14
+ it "starts with empty steps" do
15
+ transform = described_class.new(doc)
16
+ expect(transform.size).to eq(0)
17
+ end
18
+ end
19
+
20
+ describe "add_mark" do
21
+ it "adds mark step to transform" do
22
+ transform = described_class.new(doc)
23
+ mark = Prosereflect::Mark::Bold.new
24
+ transform.add_mark(0, 10, mark)
25
+ expect(transform.size).to eq(1)
26
+ end
27
+ end
28
+
29
+ describe "remove_mark" do
30
+ it "adds remove mark step to transform" do
31
+ transform = described_class.new(doc)
32
+ mark = Prosereflect::Mark::Bold.new
33
+ transform.remove_mark(0, 10, mark)
34
+ expect(transform.size).to eq(1)
35
+ end
36
+ end
37
+
38
+ describe "insert" do
39
+ it "adds insert step to transform" do
40
+ transform = described_class.new(doc)
41
+ text = Prosereflect::Text.new(text: "hello")
42
+ transform.insert(0, text)
43
+ expect(transform.size).to eq(1)
44
+ end
45
+ end
46
+
47
+ describe "delete" do
48
+ it "adds delete step to transform" do
49
+ transform = described_class.new(doc)
50
+ transform.delete(0, 5)
51
+ expect(transform.size).to eq(1)
52
+ end
53
+ end
54
+
55
+ describe "replace" do
56
+ it "adds replace step to transform" do
57
+ transform = described_class.new(doc)
58
+ slice = Prosereflect::Transform::Slice.empty
59
+ transform.replace(0, 5, slice)
60
+ expect(transform.size).to eq(1)
61
+ end
62
+
63
+ it "defaults to empty slice" do
64
+ transform = described_class.new(doc)
65
+ transform.replace(0, 5)
66
+ expect(transform.size).to eq(1)
67
+ end
68
+ end
69
+
70
+ describe "replace_with" do
71
+ it "adds replace step with nodes" do
72
+ transform = described_class.new(doc)
73
+ text = Prosereflect::Text.new(text: "x")
74
+ transform.replace_with(0, 5, text)
75
+ expect(transform.size).to eq(1)
76
+ end
77
+
78
+ it "accepts multiple nodes" do
79
+ transform = described_class.new(doc)
80
+ t1 = Prosereflect::Text.new(text: "a")
81
+ t2 = Prosereflect::Text.new(text: "b")
82
+ transform.replace_with(0, 5, t1, t2)
83
+ expect(transform.size).to eq(1)
84
+ end
85
+ end
86
+
87
+ describe "set_node_attribute" do
88
+ it "adds attr step to transform" do
89
+ transform = described_class.new(doc)
90
+ transform.set_node_attribute(0, { "level" => 2 })
91
+ expect(transform.size).to eq(1)
92
+ end
93
+ end
94
+
95
+ describe "set_doc_attribute" do
96
+ it "adds doc attr step to transform" do
97
+ transform = described_class.new(doc)
98
+ transform.set_doc_attribute({ "meta" => 1 })
99
+ expect(transform.size).to eq(1)
100
+ end
101
+ end
102
+
103
+ describe "empty?" do
104
+ it "returns true for new transform" do
105
+ transform = described_class.new(doc)
106
+ expect(transform.empty?).to be true
107
+ end
108
+
109
+ it "returns false after adding step" do
110
+ transform = described_class.new(doc)
111
+ transform.delete(0, 5)
112
+ expect(transform.empty?).to be false
113
+ end
114
+ end
115
+
116
+ describe "clone" do
117
+ it "creates new transform with same document" do
118
+ transform = described_class.new(doc)
119
+ cloned = transform.clone
120
+ expect(cloned.doc).to eq(doc)
121
+ end
122
+
123
+ it "clone does not share steps" do
124
+ transform = described_class.new(doc)
125
+ transform.delete(0, 5)
126
+ cloned = transform.clone
127
+ expect(cloned.size).to eq(0)
128
+ end
129
+ end
130
+
131
+ describe "rollback" do
132
+ it "returns self for chaining on empty transform" do
133
+ transform = described_class.new(doc)
134
+ result = transform.rollback
135
+ expect(result).to eq(transform)
136
+ end
137
+ end
138
+
139
+ describe "maps" do
140
+ it "returns empty mapping array for new transform" do
141
+ transform = described_class.new(doc)
142
+ expect(transform.maps).to eq([])
143
+ end
144
+
145
+ it "returns mapping after adding steps" do
146
+ transform = described_class.new(doc)
147
+ transform.delete(0, 5)
148
+ expect(transform.maps.length).to eq(1)
149
+ end
150
+ end
151
+
152
+ describe "size" do
153
+ it "returns number of steps" do
154
+ transform = described_class.new(doc)
155
+ expect(transform.size).to eq(0)
156
+
157
+ transform.delete(0, 5)
158
+ expect(transform.size).to eq(1)
159
+
160
+ transform.delete(0, 5)
161
+ expect(transform.size).to eq(2)
162
+ end
163
+ end
164
+
165
+ describe "add_step" do
166
+ it "returns self for chaining" do
167
+ transform = described_class.new(doc)
168
+ step = Prosereflect::Transform::ReplaceStep.new(0, 5)
169
+ result = transform.add_step(step)
170
+ expect(result).to eq(transform)
171
+ end
172
+
173
+ it "tracks mapping" do
174
+ transform = described_class.new(doc)
175
+ step = Prosereflect::Transform::ReplaceStep.new(0, 5)
176
+ transform.add_step(step)
177
+ expect(transform.maps.length).to eq(1)
178
+ end
179
+ end
180
+
181
+ describe "split" do
182
+ it "adds split step to transform" do
183
+ doc_with_content = Prosereflect::Parser.parse_document({
184
+ "type" => "doc",
185
+ "content" => [
186
+ {
187
+ "type" => "paragraph",
188
+ "content" => [
189
+ { "type" => "text", "text" => "Hello World" },
190
+ ],
191
+ },
192
+ ],
193
+ })
194
+ transform = described_class.new(doc_with_content)
195
+ transform.split(5)
196
+ expect(transform.size).to eq(1)
197
+ end
198
+ end
199
+
200
+ describe "join" do
201
+ it "adds join step to transform" do
202
+ doc_with_two_paras = Prosereflect::Parser.parse_document({
203
+ "type" => "doc",
204
+ "content" => [
205
+ {
206
+ "type" => "paragraph",
207
+ "content" => [
208
+ { "type" => "text", "text" => "Hello" },
209
+ ],
210
+ },
211
+ {
212
+ "type" => "paragraph",
213
+ "content" => [
214
+ { "type" => "text", "text" => "World" },
215
+ ],
216
+ },
217
+ ],
218
+ })
219
+ transform = described_class.new(doc_with_two_paras)
220
+ transform.join(8)
221
+ expect(transform.size).to eq(1)
222
+ end
223
+ end
224
+
225
+ describe "to_s" do
226
+ it "returns string representation" do
227
+ transform = described_class.new(doc)
228
+ expect(transform.to_s).to include("Transform")
229
+ end
230
+ end
231
+
232
+ describe "inspect" do
233
+ it "returns same as to_s" do
234
+ transform = described_class.new(doc)
235
+ expect(transform.inspect).to eq(transform.to_s)
236
+ end
237
+ end
238
+ end
data/spec/spec_helper.rb CHANGED
@@ -4,6 +4,7 @@ require "bundler/setup"
4
4
  require "yaml"
5
5
  require "json"
6
6
  require "prosereflect"
7
+ require "prosereflect/schema"
7
8
 
8
9
  # Load shared examples
9
10
  Dir[File.join(__dir__, "support", "**", "*.rb")].each { |f| require f }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prosereflect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-13 00:00:00.000000000 Z
11
+ date: 2026-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -45,6 +45,8 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".github/workflows/docs.yml"
49
+ - ".github/workflows/links.yml"
48
50
  - ".github/workflows/rake.yml"
49
51
  - ".github/workflows/release.yml"
50
52
  - ".gitignore"
@@ -55,6 +57,37 @@ files:
55
57
  - Gemfile
56
58
  - README.adoc
57
59
  - Rakefile
60
+ - docs/Gemfile
61
+ - docs/INDEX.adoc
62
+ - docs/_advanced/index.adoc
63
+ - docs/_advanced/schema.adoc
64
+ - docs/_advanced/step-map.adoc
65
+ - docs/_advanced/steps.adoc
66
+ - docs/_advanced/test-builder.adoc
67
+ - docs/_advanced/transform.adoc
68
+ - docs/_config.yml
69
+ - docs/_features/html-input.adoc
70
+ - docs/_features/html-output.adoc
71
+ - docs/_features/index.adoc
72
+ - docs/_features/marks.adoc
73
+ - docs/_features/node-types.adoc
74
+ - docs/_features/user-mentions.adoc
75
+ - docs/_guides/custom-nodes.adoc
76
+ - docs/_guides/index.adoc
77
+ - docs/_guides/round-trip-html.adoc
78
+ - docs/_guides/serialization.adoc
79
+ - docs/_pages/index.adoc
80
+ - docs/_reference/document-api.adoc
81
+ - docs/_reference/index.adoc
82
+ - docs/_reference/node-api.adoc
83
+ - docs/_reference/schema-api.adoc
84
+ - docs/_reference/transform-api.adoc
85
+ - docs/_understanding/document-model.adoc
86
+ - docs/_understanding/fragment.adoc
87
+ - docs/_understanding/index.adoc
88
+ - docs/_understanding/resolved-position.adoc
89
+ - docs/_understanding/slice.adoc
90
+ - docs/lychee.toml
58
91
  - lib/prosereflect.rb
59
92
  - lib/prosereflect/attribute.rb
60
93
  - lib/prosereflect/attribute/base.rb
@@ -66,6 +99,7 @@ files:
66
99
  - lib/prosereflect/code_block.rb
67
100
  - lib/prosereflect/code_block_wrapper.rb
68
101
  - lib/prosereflect/document.rb
102
+ - lib/prosereflect/fragment.rb
69
103
  - lib/prosereflect/hard_break.rb
70
104
  - lib/prosereflect/heading.rb
71
105
  - lib/prosereflect/horizontal_rule.rb
@@ -89,15 +123,46 @@ files:
89
123
  - lib/prosereflect/output/html.rb
90
124
  - lib/prosereflect/paragraph.rb
91
125
  - lib/prosereflect/parser.rb
126
+ - lib/prosereflect/resolved_pos.rb
127
+ - lib/prosereflect/schema.rb
128
+ - lib/prosereflect/schema/attribute.rb
129
+ - lib/prosereflect/schema/content_match.rb
130
+ - lib/prosereflect/schema/fragment.rb
131
+ - lib/prosereflect/schema/mark.rb
132
+ - lib/prosereflect/schema/mark_type.rb
133
+ - lib/prosereflect/schema/node.rb
134
+ - lib/prosereflect/schema/node_type.rb
135
+ - lib/prosereflect/schema/schema_main.rb
136
+ - lib/prosereflect/schema/spec.rb
92
137
  - lib/prosereflect/table.rb
93
138
  - lib/prosereflect/table_cell.rb
94
139
  - lib/prosereflect/table_header.rb
95
140
  - lib/prosereflect/table_row.rb
96
141
  - lib/prosereflect/text.rb
142
+ - lib/prosereflect/transform.rb
143
+ - lib/prosereflect/transform/attr_step.rb
144
+ - lib/prosereflect/transform/insert_step.rb
145
+ - lib/prosereflect/transform/mapping.rb
146
+ - lib/prosereflect/transform/mark_step.rb
147
+ - lib/prosereflect/transform/replace_around_step.rb
148
+ - lib/prosereflect/transform/replace_step.rb
149
+ - lib/prosereflect/transform/slice.rb
150
+ - lib/prosereflect/transform/step.rb
151
+ - lib/prosereflect/transform/step_map.rb
152
+ - lib/prosereflect/transform/structure.rb
153
+ - lib/prosereflect/transform/transform.rb
97
154
  - lib/prosereflect/user.rb
98
155
  - lib/prosereflect/version.rb
99
156
  - prosereflect.gemspec
100
157
  - sig/prosemirror.rbs
158
+ - spec/fixtures/documents/formatted_text.yaml
159
+ - spec/fixtures/documents/heading_paragraph.yaml
160
+ - spec/fixtures/documents/lists_doc.yaml
161
+ - spec/fixtures/documents/mixed_content.yaml
162
+ - spec/fixtures/documents/nested_doc.yaml
163
+ - spec/fixtures/documents/simple_doc.yaml
164
+ - spec/fixtures/documents/table_doc.yaml
165
+ - spec/fixtures/documents/transform_test.yaml
101
166
  - spec/fixtures/ituob-1000/ituob-1000-DP.json
102
167
  - spec/fixtures/ituob-1000/ituob-1000-DP.yaml
103
168
  - spec/fixtures/ituob-1000/ituob-1000-E118_IIN.json
@@ -134,17 +199,40 @@ files:
134
199
  - spec/fixtures/ituob-1001/ituob-1001-NNP.yaml
135
200
  - spec/fixtures/ituob-1001/ituob-1001-Q708_ISPC.json
136
201
  - spec/fixtures/ituob-1001/ituob-1001-Q708_ISPC.yaml
202
+ - spec/fixtures/schema/custom_schema.rb
203
+ - spec/fixtures/schema/test_schema.rb
204
+ - spec/fixtures/test_builder/helpers.rb
137
205
  - spec/prosereflect/document_spec.rb
206
+ - spec/prosereflect/fragment_spec.rb
138
207
  - spec/prosereflect/hard_break_spec.rb
139
208
  - spec/prosereflect/input/html_spec.rb
140
209
  - spec/prosereflect/node_spec.rb
141
210
  - spec/prosereflect/output/html_spec.rb
211
+ - spec/prosereflect/output/whitespace_spec.rb
142
212
  - spec/prosereflect/paragraph_spec.rb
213
+ - spec/prosereflect/parser/round_trip_spec.rb
143
214
  - spec/prosereflect/parser_spec.rb
215
+ - spec/prosereflect/resolved_pos_spec.rb
216
+ - spec/prosereflect/schema/conftest.rb
217
+ - spec/prosereflect/schema/content_match_spec.rb
218
+ - spec/prosereflect/schema/mark_spec.rb
219
+ - spec/prosereflect/schema/mark_type_spec.rb
220
+ - spec/prosereflect/schema/node_type_spec.rb
221
+ - spec/prosereflect/schema/schema_spec.rb
144
222
  - spec/prosereflect/table_cell_spec.rb
145
223
  - spec/prosereflect/table_row_spec.rb
146
224
  - spec/prosereflect/table_spec.rb
225
+ - spec/prosereflect/test_builder/marks_spec.rb
147
226
  - spec/prosereflect/text_spec.rb
227
+ - spec/prosereflect/transform/equivalence_spec.rb
228
+ - spec/prosereflect/transform/mapping_spec.rb
229
+ - spec/prosereflect/transform/replace_spec.rb
230
+ - spec/prosereflect/transform/replace_step_spec.rb
231
+ - spec/prosereflect/transform/slice_spec.rb
232
+ - spec/prosereflect/transform/step_map_spec.rb
233
+ - spec/prosereflect/transform/step_spec.rb
234
+ - spec/prosereflect/transform/structure_spec.rb
235
+ - spec/prosereflect/transform/transform_spec.rb
148
236
  - spec/prosereflect/user_spec.rb
149
237
  - spec/prosereflect_spec.rb
150
238
  - spec/spec_helper.rb