prosereflect 0.1.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 +7 -0
- data/.github/workflows/rake.yml +15 -0
- data/.github/workflows/release.yml +25 -0
- data/.gitignore +12 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +228 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/Gemfile +10 -0
- data/README.adoc +268 -0
- data/Rakefile +12 -0
- data/debug_loading.rb +34 -0
- data/lib/prosereflect/document.rb +63 -0
- data/lib/prosereflect/hard_break.rb +22 -0
- data/lib/prosereflect/node.rb +77 -0
- data/lib/prosereflect/paragraph.rb +50 -0
- data/lib/prosereflect/parser.rb +56 -0
- data/lib/prosereflect/table.rb +64 -0
- data/lib/prosereflect/table_cell.rb +37 -0
- data/lib/prosereflect/table_row.rb +32 -0
- data/lib/prosereflect/text.rb +37 -0
- data/lib/prosereflect/version.rb +5 -0
- data/lib/prosereflect.rb +17 -0
- data/prosereflect.gemspec +33 -0
- data/sig/prosemirror.rbs +4 -0
- data/spec/fixtures/ituob-1000/ituob-1000-DP.json +366 -0
- data/spec/fixtures/ituob-1000/ituob-1000-DP.yaml +182 -0
- data/spec/fixtures/ituob-1000/ituob-1000-E118_IIN.json +381 -0
- data/spec/fixtures/ituob-1000/ituob-1000-E118_IIN.yaml +182 -0
- data/spec/fixtures/ituob-1000/ituob-1000-E164_ACN.json +203 -0
- data/spec/fixtures/ituob-1000/ituob-1000-E164_ACN.yaml +98 -0
- data/spec/fixtures/ituob-1000/ituob-1000-E212_MNC.json +202 -0
- data/spec/fixtures/ituob-1000/ituob-1000-E212_MNC.yaml +101 -0
- data/spec/fixtures/ituob-1000/ituob-1000-F32_TDI.json +6948 -0
- data/spec/fixtures/ituob-1000/ituob-1000-F32_TDI.yaml +3519 -0
- data/spec/fixtures/ituob-1000/ituob-1000-M1400_ICC.json +529 -0
- data/spec/fixtures/ituob-1000/ituob-1000-M1400_ICC.yaml +263 -0
- data/spec/fixtures/ituob-1000/ituob-1000-NNP.json +288 -0
- data/spec/fixtures/ituob-1000/ituob-1000-NNP.yaml +152 -0
- data/spec/fixtures/ituob-1000/ituob-1000-Q708_ISPC.json +1534 -0
- data/spec/fixtures/ituob-1000/ituob-1000-Q708_ISPC.yaml +789 -0
- data/spec/fixtures/ituob-1000/ituob-1000-Q708_SANC.json +252 -0
- data/spec/fixtures/ituob-1000/ituob-1000-Q708_SANC.yaml +123 -0
- data/spec/fixtures/ituob-1000/ituob-1000-R_SP_LM.V.json +428 -0
- data/spec/fixtures/ituob-1000/ituob-1000-R_SP_LM.V.yaml +208 -0
- data/spec/fixtures/ituob-1000/ituob-1000-T35_NA.json +621 -0
- data/spec/fixtures/ituob-1000/ituob-1000-T35_NA.yaml +317 -0
- data/spec/fixtures/ituob-1001/ituob-1001-DP.json +532 -0
- data/spec/fixtures/ituob-1001/ituob-1001-DP.yaml +266 -0
- data/spec/fixtures/ituob-1001/ituob-1001-E118_IIN.json +1093 -0
- data/spec/fixtures/ituob-1001/ituob-1001-E118_IIN.yaml +519 -0
- data/spec/fixtures/ituob-1001/ituob-1001-E164_ACN.json +449 -0
- data/spec/fixtures/ituob-1001/ituob-1001-E164_ACN.yaml +214 -0
- data/spec/fixtures/ituob-1001/ituob-1001-E164_CC.json +271 -0
- data/spec/fixtures/ituob-1001/ituob-1001-E164_CC.yaml +136 -0
- data/spec/fixtures/ituob-1001/ituob-1001-E212_MNC.json +199 -0
- data/spec/fixtures/ituob-1001/ituob-1001-E212_MNC.yaml +99 -0
- data/spec/fixtures/ituob-1001/ituob-1001-NNP.json +288 -0
- data/spec/fixtures/ituob-1001/ituob-1001-NNP.yaml +152 -0
- data/spec/fixtures/ituob-1001/ituob-1001-Q708_ISPC.json +960 -0
- data/spec/fixtures/ituob-1001/ituob-1001-Q708_ISPC.yaml +487 -0
- data/spec/prosereflect/document_spec.rb +149 -0
- data/spec/prosereflect/hard_break_spec.rb +51 -0
- data/spec/prosereflect/node_spec.rb +256 -0
- data/spec/prosereflect/paragraph_spec.rb +152 -0
- data/spec/prosereflect/parser_spec.rb +129 -0
- data/spec/prosereflect/table_cell_spec.rb +114 -0
- data/spec/prosereflect/table_row_spec.rb +77 -0
- data/spec/prosereflect/table_spec.rb +144 -0
- data/spec/prosereflect/text_spec.rb +116 -0
- data/spec/prosereflect/version_spec.rb +11 -0
- data/spec/prosereflect_spec.rb +57 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/matchers.rb +131 -0
- data/spec/support/shared_examples.rb +220 -0
- metadata +133 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_examples 'a parsable format' do |format|
|
4
|
+
it "parses #{format} content correctly" do
|
5
|
+
document = case format
|
6
|
+
when :yaml
|
7
|
+
Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
|
8
|
+
when :json
|
9
|
+
Prosereflect::Parser.parse_document(JSON.parse(file_content))
|
10
|
+
end
|
11
|
+
|
12
|
+
expect(document).to be_a(Prosereflect::Document)
|
13
|
+
expect(document.content).not_to be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it "maintains structure after #{format} round-trip" do
|
17
|
+
# Parse the original content
|
18
|
+
original_data = case format
|
19
|
+
when :yaml
|
20
|
+
YAML.safe_load(file_content)
|
21
|
+
when :json
|
22
|
+
JSON.parse(file_content)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create a document from the data
|
26
|
+
document = Prosereflect::Parser.parse_document(original_data)
|
27
|
+
|
28
|
+
# Convert back to the original format
|
29
|
+
round_trip_data = case format
|
30
|
+
when :yaml
|
31
|
+
YAML.safe_load(document.to_yaml)
|
32
|
+
when :json
|
33
|
+
JSON.parse(document.to_json)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Compare the structures
|
37
|
+
case format
|
38
|
+
when :yaml
|
39
|
+
expect(round_trip_data).to be_equivalent_yaml(original_data)
|
40
|
+
when :json
|
41
|
+
expect(round_trip_data).to be_equivalent_json(original_data)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
RSpec.shared_examples 'a document with tables' do
|
47
|
+
it 'contains at least one table' do
|
48
|
+
document = case file_content
|
49
|
+
when String
|
50
|
+
if file_content.strip.start_with?('{')
|
51
|
+
Prosereflect::Parser.parse_document(JSON.parse(file_content))
|
52
|
+
else
|
53
|
+
Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
|
54
|
+
end
|
55
|
+
else
|
56
|
+
Prosereflect::Parser.parse_document(file_content)
|
57
|
+
end
|
58
|
+
|
59
|
+
expect(document.tables.size).to be > 0
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'has tables with rows and cells' do
|
63
|
+
document = case file_content
|
64
|
+
when String
|
65
|
+
if file_content.strip.start_with?('{')
|
66
|
+
Prosereflect::Parser.parse_document(JSON.parse(file_content))
|
67
|
+
else
|
68
|
+
Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
|
69
|
+
end
|
70
|
+
else
|
71
|
+
Prosereflect::Parser.parse_document(file_content)
|
72
|
+
end
|
73
|
+
|
74
|
+
table = document.tables.first
|
75
|
+
expect(table.rows.size).to be > 0
|
76
|
+
expect(table.rows.first.cells.size).to be > 0
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
RSpec.shared_examples 'document traversal' do
|
81
|
+
it 'can find nodes by type' do
|
82
|
+
document = case file_content
|
83
|
+
when String
|
84
|
+
if file_content.strip.start_with?('{')
|
85
|
+
Prosereflect::Parser.parse_document(JSON.parse(file_content))
|
86
|
+
else
|
87
|
+
Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
|
88
|
+
end
|
89
|
+
else
|
90
|
+
Prosereflect::Parser.parse_document(file_content)
|
91
|
+
end
|
92
|
+
|
93
|
+
expect(document.find_all('table').size).to be > 0
|
94
|
+
expect(document.find_all('paragraph').size).to be >= 0
|
95
|
+
expect(document.find_all('text').size).to be > 0
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
RSpec.shared_examples 'text content extraction' do
|
100
|
+
it 'extracts text content from nodes' do
|
101
|
+
document = case file_content
|
102
|
+
when String
|
103
|
+
if file_content.strip.start_with?('{')
|
104
|
+
Prosereflect::Parser.parse_document(JSON.parse(file_content))
|
105
|
+
else
|
106
|
+
Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
|
107
|
+
end
|
108
|
+
else
|
109
|
+
Prosereflect::Parser.parse_document(file_content)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Get text from the first paragraph or table cell that contains text
|
113
|
+
text_container = document.find_first('paragraph') || document.find_first('table_cell')
|
114
|
+
|
115
|
+
if text_container
|
116
|
+
expect(text_container.text_content).to be_a(String)
|
117
|
+
expect(text_container.text_content).not_to be_empty if text_container.find_first('text')
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
RSpec.shared_examples 'document creation' do
|
123
|
+
it 'creates an empty document' do
|
124
|
+
document = Prosereflect::Document.create
|
125
|
+
expect(document).to be_a(Prosereflect::Document)
|
126
|
+
expect(document.type).to eq('doc')
|
127
|
+
expect(document.content).to eq([])
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'creates a document with attributes' do
|
131
|
+
attrs = { 'version' => '1.0' }
|
132
|
+
document = Prosereflect::Document.create(attrs)
|
133
|
+
expect(document.attrs).to eq(attrs)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'adds paragraphs to a document' do
|
137
|
+
document = Prosereflect::Document.create
|
138
|
+
paragraph = document.add_paragraph('Test paragraph')
|
139
|
+
|
140
|
+
expect(document.content.size).to eq(1)
|
141
|
+
expect(paragraph).to be_a(Prosereflect::Paragraph)
|
142
|
+
expect(paragraph.text_content).to eq('Test paragraph')
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'adds tables to a document' do
|
146
|
+
document = Prosereflect::Document.create
|
147
|
+
table = document.add_table
|
148
|
+
|
149
|
+
expect(document.content.size).to eq(1)
|
150
|
+
expect(table).to be_a(Prosereflect::Table)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Helper for parsing any format of content
|
155
|
+
RSpec.shared_examples 'format parsing' do
|
156
|
+
let(:document) do
|
157
|
+
case file_content
|
158
|
+
when String
|
159
|
+
if file_content.strip.start_with?('{')
|
160
|
+
Prosereflect::Parser.parse_document(JSON.parse(file_content))
|
161
|
+
else
|
162
|
+
Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
|
163
|
+
end
|
164
|
+
else
|
165
|
+
Prosereflect::Parser.parse_document(file_content)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
RSpec.shared_examples 'format round-trip' do |format|
|
171
|
+
it "maintains document structure after #{format} round-trip" do
|
172
|
+
# Create a rich document
|
173
|
+
document = Prosereflect::Document.create
|
174
|
+
|
175
|
+
# Add paragraph with formatted text
|
176
|
+
para = document.add_paragraph('Plain text')
|
177
|
+
para.add_text(' bold text', [{ 'type' => 'bold' }])
|
178
|
+
para.add_hard_break
|
179
|
+
para.add_text('After line break', [{ 'type' => 'italic' }])
|
180
|
+
|
181
|
+
# Add a table
|
182
|
+
table = document.add_table
|
183
|
+
table.add_header(['Header 1', 'Header 2', 'Header 3'])
|
184
|
+
table.add_row(%w[R1C1 R1C2 R1C3])
|
185
|
+
table.add_row(%w[R2C1 R2C2 R2C3])
|
186
|
+
|
187
|
+
# Add another paragraph
|
188
|
+
document.add_paragraph('Concluding paragraph')
|
189
|
+
|
190
|
+
# Convert to specified format and back
|
191
|
+
parsed_doc = round_trip_conversion(document, format)
|
192
|
+
|
193
|
+
# Verify structure is maintained
|
194
|
+
expect(parsed_doc.paragraphs.size).to eq(document.paragraphs.size)
|
195
|
+
expect(parsed_doc.tables.size).to eq(document.tables.size)
|
196
|
+
expect(parsed_doc.find_all('hard_break').size).to eq(document.find_all('hard_break').size)
|
197
|
+
|
198
|
+
# Verify table structure
|
199
|
+
table_in_parsed = parsed_doc.first_table
|
200
|
+
expect(table_in_parsed.rows.size).to eq(document.first_table.rows.size)
|
201
|
+
expect(table_in_parsed.header_row.cells.size).to eq(document.first_table.header_row.cells.size)
|
202
|
+
end
|
203
|
+
|
204
|
+
def round_trip_conversion(doc, format)
|
205
|
+
case format
|
206
|
+
when :yaml
|
207
|
+
yaml = doc.to_yaml
|
208
|
+
parsed = Prosereflect::Parser.parse_document(YAML.safe_load(yaml))
|
209
|
+
# Compare structures
|
210
|
+
expect(YAML.safe_load(parsed.to_yaml)).to be_equivalent_yaml(YAML.safe_load(doc.to_yaml))
|
211
|
+
parsed
|
212
|
+
when :json
|
213
|
+
json = doc.to_json
|
214
|
+
parsed = Prosereflect::Parser.parse_document(JSON.parse(json))
|
215
|
+
# Compare structures
|
216
|
+
expect(JSON.parse(parsed.to_json)).to be_equivalent_json(JSON.parse(doc.to_json))
|
217
|
+
parsed
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: prosereflect
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ribose
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-05-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: lutaml-model
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.7'
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
- open.source@ribose.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".github/workflows/rake.yml"
|
35
|
+
- ".github/workflows/release.yml"
|
36
|
+
- ".gitignore"
|
37
|
+
- ".rubocop.yml"
|
38
|
+
- ".rubocop_todo.yml"
|
39
|
+
- CODE_OF_CONDUCT.md
|
40
|
+
- Gemfile
|
41
|
+
- README.adoc
|
42
|
+
- Rakefile
|
43
|
+
- debug_loading.rb
|
44
|
+
- lib/prosereflect.rb
|
45
|
+
- lib/prosereflect/document.rb
|
46
|
+
- lib/prosereflect/hard_break.rb
|
47
|
+
- lib/prosereflect/node.rb
|
48
|
+
- lib/prosereflect/paragraph.rb
|
49
|
+
- lib/prosereflect/parser.rb
|
50
|
+
- lib/prosereflect/table.rb
|
51
|
+
- lib/prosereflect/table_cell.rb
|
52
|
+
- lib/prosereflect/table_row.rb
|
53
|
+
- lib/prosereflect/text.rb
|
54
|
+
- lib/prosereflect/version.rb
|
55
|
+
- prosereflect.gemspec
|
56
|
+
- sig/prosemirror.rbs
|
57
|
+
- spec/fixtures/ituob-1000/ituob-1000-DP.json
|
58
|
+
- spec/fixtures/ituob-1000/ituob-1000-DP.yaml
|
59
|
+
- spec/fixtures/ituob-1000/ituob-1000-E118_IIN.json
|
60
|
+
- spec/fixtures/ituob-1000/ituob-1000-E118_IIN.yaml
|
61
|
+
- spec/fixtures/ituob-1000/ituob-1000-E164_ACN.json
|
62
|
+
- spec/fixtures/ituob-1000/ituob-1000-E164_ACN.yaml
|
63
|
+
- spec/fixtures/ituob-1000/ituob-1000-E212_MNC.json
|
64
|
+
- spec/fixtures/ituob-1000/ituob-1000-E212_MNC.yaml
|
65
|
+
- spec/fixtures/ituob-1000/ituob-1000-F32_TDI.json
|
66
|
+
- spec/fixtures/ituob-1000/ituob-1000-F32_TDI.yaml
|
67
|
+
- spec/fixtures/ituob-1000/ituob-1000-M1400_ICC.json
|
68
|
+
- spec/fixtures/ituob-1000/ituob-1000-M1400_ICC.yaml
|
69
|
+
- spec/fixtures/ituob-1000/ituob-1000-NNP.json
|
70
|
+
- spec/fixtures/ituob-1000/ituob-1000-NNP.yaml
|
71
|
+
- spec/fixtures/ituob-1000/ituob-1000-Q708_ISPC.json
|
72
|
+
- spec/fixtures/ituob-1000/ituob-1000-Q708_ISPC.yaml
|
73
|
+
- spec/fixtures/ituob-1000/ituob-1000-Q708_SANC.json
|
74
|
+
- spec/fixtures/ituob-1000/ituob-1000-Q708_SANC.yaml
|
75
|
+
- spec/fixtures/ituob-1000/ituob-1000-R_SP_LM.V.json
|
76
|
+
- spec/fixtures/ituob-1000/ituob-1000-R_SP_LM.V.yaml
|
77
|
+
- spec/fixtures/ituob-1000/ituob-1000-T35_NA.json
|
78
|
+
- spec/fixtures/ituob-1000/ituob-1000-T35_NA.yaml
|
79
|
+
- spec/fixtures/ituob-1001/ituob-1001-DP.json
|
80
|
+
- spec/fixtures/ituob-1001/ituob-1001-DP.yaml
|
81
|
+
- spec/fixtures/ituob-1001/ituob-1001-E118_IIN.json
|
82
|
+
- spec/fixtures/ituob-1001/ituob-1001-E118_IIN.yaml
|
83
|
+
- spec/fixtures/ituob-1001/ituob-1001-E164_ACN.json
|
84
|
+
- spec/fixtures/ituob-1001/ituob-1001-E164_ACN.yaml
|
85
|
+
- spec/fixtures/ituob-1001/ituob-1001-E164_CC.json
|
86
|
+
- spec/fixtures/ituob-1001/ituob-1001-E164_CC.yaml
|
87
|
+
- spec/fixtures/ituob-1001/ituob-1001-E212_MNC.json
|
88
|
+
- spec/fixtures/ituob-1001/ituob-1001-E212_MNC.yaml
|
89
|
+
- spec/fixtures/ituob-1001/ituob-1001-NNP.json
|
90
|
+
- spec/fixtures/ituob-1001/ituob-1001-NNP.yaml
|
91
|
+
- spec/fixtures/ituob-1001/ituob-1001-Q708_ISPC.json
|
92
|
+
- spec/fixtures/ituob-1001/ituob-1001-Q708_ISPC.yaml
|
93
|
+
- spec/prosereflect/document_spec.rb
|
94
|
+
- spec/prosereflect/hard_break_spec.rb
|
95
|
+
- spec/prosereflect/node_spec.rb
|
96
|
+
- spec/prosereflect/paragraph_spec.rb
|
97
|
+
- spec/prosereflect/parser_spec.rb
|
98
|
+
- spec/prosereflect/table_cell_spec.rb
|
99
|
+
- spec/prosereflect/table_row_spec.rb
|
100
|
+
- spec/prosereflect/table_spec.rb
|
101
|
+
- spec/prosereflect/text_spec.rb
|
102
|
+
- spec/prosereflect/version_spec.rb
|
103
|
+
- spec/prosereflect_spec.rb
|
104
|
+
- spec/spec_helper.rb
|
105
|
+
- spec/support/matchers.rb
|
106
|
+
- spec/support/shared_examples.rb
|
107
|
+
homepage: https://github.com/metanorma/prosereflect
|
108
|
+
licenses:
|
109
|
+
- BSD-2-Clause
|
110
|
+
metadata:
|
111
|
+
homepage_uri: https://github.com/metanorma/prosereflect
|
112
|
+
source_code_uri: https://github.com/metanorma/prosereflect
|
113
|
+
bug_tracker_uri: https://github.com/metanorma/prosereflect/issues
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 2.6.0
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubygems_version: 3.5.22
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: Ruby model accessor for prosereflect document trees.
|
133
|
+
test_files: []
|