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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +4 -0
  3. data/.github/workflows/release.yml +5 -0
  4. data/.rubocop.yml +19 -1
  5. data/.rubocop_todo.yml +141 -191
  6. data/CLAUDE.md +78 -0
  7. data/Gemfile +8 -4
  8. data/Rakefile +3 -3
  9. data/lib/prosereflect/attribute/base.rb +4 -6
  10. data/lib/prosereflect/attribute/bold.rb +2 -4
  11. data/lib/prosereflect/attribute/href.rb +1 -3
  12. data/lib/prosereflect/attribute/id.rb +7 -7
  13. data/lib/prosereflect/attribute.rb +4 -7
  14. data/lib/prosereflect/blockquote.rb +10 -11
  15. data/lib/prosereflect/bullet_list.rb +16 -15
  16. data/lib/prosereflect/code_block.rb +26 -26
  17. data/lib/prosereflect/code_block_wrapper.rb +12 -13
  18. data/lib/prosereflect/document.rb +14 -22
  19. data/lib/prosereflect/hard_break.rb +6 -6
  20. data/lib/prosereflect/heading.rb +14 -15
  21. data/lib/prosereflect/horizontal_rule.rb +14 -14
  22. data/lib/prosereflect/image.rb +23 -23
  23. data/lib/prosereflect/input/html.rb +83 -104
  24. data/lib/prosereflect/input.rb +7 -0
  25. data/lib/prosereflect/list_item.rb +11 -12
  26. data/lib/prosereflect/mark/base.rb +9 -11
  27. data/lib/prosereflect/mark/bold.rb +1 -3
  28. data/lib/prosereflect/mark/code.rb +1 -3
  29. data/lib/prosereflect/mark/italic.rb +1 -3
  30. data/lib/prosereflect/mark/link.rb +1 -3
  31. data/lib/prosereflect/mark/strike.rb +1 -3
  32. data/lib/prosereflect/mark/subscript.rb +1 -3
  33. data/lib/prosereflect/mark/superscript.rb +1 -3
  34. data/lib/prosereflect/mark/underline.rb +1 -3
  35. data/lib/prosereflect/mark.rb +9 -5
  36. data/lib/prosereflect/node.rb +31 -31
  37. data/lib/prosereflect/ordered_list.rb +15 -14
  38. data/lib/prosereflect/output/html.rb +52 -50
  39. data/lib/prosereflect/output.rb +7 -0
  40. data/lib/prosereflect/paragraph.rb +11 -13
  41. data/lib/prosereflect/parser.rb +47 -66
  42. data/lib/prosereflect/table.rb +12 -13
  43. data/lib/prosereflect/table_cell.rb +13 -13
  44. data/lib/prosereflect/table_header.rb +17 -17
  45. data/lib/prosereflect/table_row.rb +12 -12
  46. data/lib/prosereflect/text.rb +11 -11
  47. data/lib/prosereflect/user.rb +15 -15
  48. data/lib/prosereflect/version.rb +1 -1
  49. data/lib/prosereflect.rb +27 -17
  50. data/prosereflect.gemspec +17 -16
  51. data/spec/prosereflect/document_spec.rb +332 -330
  52. data/spec/prosereflect/hard_break_spec.rb +125 -125
  53. data/spec/prosereflect/input/html_spec.rb +522 -522
  54. data/spec/prosereflect/node_spec.rb +183 -182
  55. data/spec/prosereflect/output/html_spec.rb +105 -105
  56. data/spec/prosereflect/paragraph_spec.rb +275 -274
  57. data/spec/prosereflect/parser_spec.rb +185 -180
  58. data/spec/prosereflect/table_cell_spec.rb +183 -183
  59. data/spec/prosereflect/table_row_spec.rb +149 -149
  60. data/spec/prosereflect/table_spec.rb +320 -318
  61. data/spec/prosereflect/text_spec.rb +133 -132
  62. data/spec/prosereflect/user_spec.rb +31 -28
  63. data/spec/prosereflect_spec.rb +28 -26
  64. data/spec/spec_helper.rb +6 -6
  65. data/spec/support/matchers.rb +6 -6
  66. data/spec/support/shared_examples.rb +49 -49
  67. metadata +8 -5
  68. data/spec/prosereflect/version_spec.rb +0 -11
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml'
4
- require 'json'
3
+ require "yaml"
4
+ require "json"
5
5
 
6
6
  # Custom RSpec matcher for comparing JSON structures
7
7
  RSpec::Matchers.define :be_equivalent_json do |expected|
@@ -64,7 +64,7 @@ RSpec::Matchers.define :have_equivalent_structure do |expected|
64
64
  # Parse strings if needed
65
65
  expected_data = case expected
66
66
  when String
67
- if expected.strip.start_with?('{', '[')
67
+ if expected.strip.start_with?("{", "[")
68
68
  begin
69
69
  JSON.parse(expected)
70
70
  rescue StandardError
@@ -79,7 +79,7 @@ RSpec::Matchers.define :have_equivalent_structure do |expected|
79
79
 
80
80
  actual_data = case actual
81
81
  when String
82
- if actual.strip.start_with?('{', '[')
82
+ if actual.strip.start_with?("{", "[")
83
83
  begin
84
84
  JSON.parse(actual)
85
85
  rescue StandardError
@@ -98,7 +98,7 @@ RSpec::Matchers.define :have_equivalent_structure do |expected|
98
98
  failure_message do |actual|
99
99
  expected_data = case expected
100
100
  when String
101
- if expected.strip.start_with?('{', '[')
101
+ if expected.strip.start_with?("{", "[")
102
102
  begin
103
103
  JSON.parse(expected)
104
104
  rescue StandardError
@@ -113,7 +113,7 @@ RSpec::Matchers.define :have_equivalent_structure do |expected|
113
113
 
114
114
  actual_data = case actual
115
115
  when String
116
- if actual.strip.start_with?('{', '[')
116
+ if actual.strip.start_with?("{", "[")
117
117
  begin
118
118
  JSON.parse(actual)
119
119
  rescue StandardError
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.shared_examples 'a parsable format' do |format|
3
+ RSpec.shared_examples "a parsable format" do |format|
4
4
  it "parses #{format} content correctly" do
5
5
  document = case format
6
6
  when :yaml
@@ -43,11 +43,11 @@ RSpec.shared_examples 'a parsable format' do |format|
43
43
  end
44
44
  end
45
45
 
46
- RSpec.shared_examples 'a document with tables' do
47
- it 'contains at least one table' do
46
+ RSpec.shared_examples "a document with tables" do
47
+ it "contains at least one table" do
48
48
  document = case file_content
49
49
  when String
50
- if file_content.strip.start_with?('{')
50
+ if file_content.strip.start_with?("{")
51
51
  Prosereflect::Parser.parse_document(JSON.parse(file_content))
52
52
  else
53
53
  Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
@@ -59,10 +59,10 @@ RSpec.shared_examples 'a document with tables' do
59
59
  expect(document.tables.size).to be > 0
60
60
  end
61
61
 
62
- it 'has tables with rows and cells' do
62
+ it "has tables with rows and cells" do
63
63
  document = case file_content
64
64
  when String
65
- if file_content.strip.start_with?('{')
65
+ if file_content.strip.start_with?("{")
66
66
  Prosereflect::Parser.parse_document(JSON.parse(file_content))
67
67
  else
68
68
  Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
@@ -77,11 +77,11 @@ RSpec.shared_examples 'a document with tables' do
77
77
  end
78
78
  end
79
79
 
80
- RSpec.shared_examples 'document traversal' do
81
- it 'can find nodes by type' do
80
+ RSpec.shared_examples "document traversal" do
81
+ it "can find nodes by type" do
82
82
  document = case file_content
83
83
  when String
84
- if file_content.strip.start_with?('{')
84
+ if file_content.strip.start_with?("{")
85
85
  Prosereflect::Parser.parse_document(JSON.parse(file_content))
86
86
  else
87
87
  Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
@@ -90,17 +90,17 @@ RSpec.shared_examples 'document traversal' do
90
90
  Prosereflect::Parser.parse_document(file_content)
91
91
  end
92
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
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
96
  end
97
97
  end
98
98
 
99
- RSpec.shared_examples 'text content extraction' do
100
- it 'extracts text content from nodes' do
99
+ RSpec.shared_examples "text content extraction" do
100
+ it "extracts text content from nodes" do
101
101
  document = case file_content
102
102
  when String
103
- if file_content.strip.start_with?('{')
103
+ if file_content.strip.start_with?("{")
104
104
  Prosereflect::Parser.parse_document(JSON.parse(file_content))
105
105
  else
106
106
  Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
@@ -110,39 +110,39 @@ RSpec.shared_examples 'text content extraction' do
110
110
  end
111
111
 
112
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')
113
+ text_container = document.find_first("paragraph") || document.find_first("table_cell")
114
114
 
115
115
  if text_container
116
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')
117
+ expect(text_container.text_content).not_to be_empty if text_container.find_first("text")
118
118
  end
119
119
  end
120
120
  end
121
121
 
122
- RSpec.shared_examples 'document creation' do
123
- it 'creates an empty document' do
122
+ RSpec.shared_examples "document creation" do
123
+ it "creates an empty document" do
124
124
  document = Prosereflect::Document.create
125
125
  expect(document).to be_a(Prosereflect::Document)
126
- expect(document.type).to eq('doc')
126
+ expect(document.type).to eq("doc")
127
127
  expect(document.content).to eq([])
128
128
  end
129
129
 
130
- it 'creates a document with attributes' do
131
- attrs = { 'version' => '1.0' }
130
+ it "creates a document with attributes" do
131
+ attrs = { "version" => "1.0" }
132
132
  document = Prosereflect::Document.new(attrs: attrs)
133
133
  expect(document.attrs).to eq(attrs)
134
134
  end
135
135
 
136
- it 'adds paragraphs to a document' do
136
+ it "adds paragraphs to a document" do
137
137
  document = Prosereflect::Document.create
138
- paragraph = document.add_paragraph('Test paragraph')
138
+ paragraph = document.add_paragraph("Test paragraph")
139
139
 
140
140
  expect(document.content.size).to eq(1)
141
141
  expect(paragraph).to be_a(Prosereflect::Paragraph)
142
- expect(paragraph.text_content).to eq('Test paragraph')
142
+ expect(paragraph.text_content).to eq("Test paragraph")
143
143
  end
144
144
 
145
- it 'adds tables to a document' do
145
+ it "adds tables to a document" do
146
146
  document = Prosereflect::Document.create
147
147
  table = document.add_table
148
148
 
@@ -152,11 +152,11 @@ RSpec.shared_examples 'document creation' do
152
152
  end
153
153
 
154
154
  # Helper for parsing any format of content
155
- RSpec.shared_examples 'format parsing' do
155
+ RSpec.shared_context "format parsing" do
156
156
  let(:document) do
157
157
  case file_content
158
158
  when String
159
- if file_content.strip.start_with?('{')
159
+ if file_content.strip.start_with?("{")
160
160
  Prosereflect::Parser.parse_document(JSON.parse(file_content))
161
161
  else
162
162
  Prosereflect::Parser.parse_document(YAML.safe_load(file_content))
@@ -167,25 +167,25 @@ RSpec.shared_examples 'format parsing' do
167
167
  end
168
168
  end
169
169
 
170
- RSpec.shared_examples 'format round-trip' do |format|
170
+ RSpec.shared_examples "format round-trip" do |format|
171
171
  it "maintains document structure after #{format} round-trip" do
172
172
  # Create a rich document
173
173
  document = Prosereflect::Document.create
174
174
 
175
175
  # Add paragraph with formatted text
176
- para = document.add_paragraph('Plain text')
177
- para.add_text(' bold text', [{ 'type' => 'bold' }])
176
+ para = document.add_paragraph("Plain text")
177
+ para.add_text(" bold text", [{ "type" => "bold" }])
178
178
  para.add_hard_break
179
- para.add_text('After line break', [{ 'type' => 'italic' }])
179
+ para.add_text("After line break", [{ "type" => "italic" }])
180
180
 
181
181
  # Add a table
182
182
  table = document.add_table
183
- table.add_header(['Header 1', 'Header 2', 'Header 3'])
183
+ table.add_header(["Header 1", "Header 2", "Header 3"])
184
184
  table.add_row(%w[R1C1 R1C2 R1C3])
185
185
  table.add_row(%w[R2C1 R2C2 R2C3])
186
186
 
187
187
  # Add another paragraph
188
- document.add_paragraph('Concluding paragraph')
188
+ document.add_paragraph("Concluding paragraph")
189
189
 
190
190
  # Convert to specified format and back
191
191
  parsed_doc = round_trip_conversion(document, format)
@@ -193,12 +193,12 @@ RSpec.shared_examples 'format round-trip' do |format|
193
193
  # Verify structure is maintained
194
194
  expect(parsed_doc.paragraphs.size).to eq(document.paragraphs.size)
195
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)
196
+ expect(parsed_doc.find_all("hard_break").size).to eq(document.find_all("hard_break").size)
197
197
 
198
198
  # Verify table structure
199
- table_in_parsed = parsed_doc.find_first('table')
200
- expect(table_in_parsed.rows.size).to eq(document.find_first('table').rows.size)
201
- expect(table_in_parsed.header_row.cells.size).to eq(document.find_first('table').header_row.cells.size)
199
+ table_in_parsed = parsed_doc.find_first("table")
200
+ expect(table_in_parsed.rows.size).to eq(document.find_first("table").rows.size)
201
+ expect(table_in_parsed.header_row.cells.size).to eq(document.find_first("table").header_row.cells.size)
202
202
  end
203
203
 
204
204
  def round_trip_conversion(doc, format)
@@ -214,21 +214,21 @@ RSpec.shared_examples 'format round-trip' do |format|
214
214
  end
215
215
  end
216
216
 
217
- RSpec.shared_examples 'html conversion' do
218
- it 'converts to HTML and back' do
217
+ RSpec.shared_examples "html conversion" do
218
+ it "converts to HTML and back" do
219
219
  # Create a document with various elements
220
220
  document = Prosereflect::Document.create
221
221
 
222
222
  # Add paragraph with formatted text
223
- para = document.add_paragraph('Plain text')
224
- para.add_text(' bold text', [Prosereflect::Mark::Bold.new])
223
+ para = document.add_paragraph("Plain text")
224
+ para.add_text(" bold text", [Prosereflect::Mark::Bold.new])
225
225
  para.add_hard_break
226
- para.add_text('After line break', [Prosereflect::Mark::Italic.new])
226
+ para.add_text("After line break", [Prosereflect::Mark::Italic.new])
227
227
 
228
228
  # Add a table
229
229
  table = document.add_table
230
- table.add_header(['Header 1', 'Header 2'])
231
- table.add_row(['Cell 1', 'Cell 2'])
230
+ table.add_header(["Header 1", "Header 2"])
231
+ table.add_row(["Cell 1", "Cell 2"])
232
232
 
233
233
  # Convert to HTML
234
234
  html = Prosereflect::Output::Html.convert(document)
@@ -241,9 +241,9 @@ RSpec.shared_examples 'html conversion' do
241
241
 
242
242
  # Check content was preserved
243
243
  expect(parsed_doc.content.size).to be > 0
244
- expect(parsed_doc.text_content).to include('Plain text')
245
- expect(parsed_doc.text_content).to include('bold text')
246
- expect(parsed_doc.text_content).to include('After line break')
247
- expect(parsed_doc.find_all('table').size).to eq(1)
244
+ expect(parsed_doc.text_content).to include("Plain text")
245
+ expect(parsed_doc.text_content).to include("bold text")
246
+ expect(parsed_doc.text_content).to include("After line break")
247
+ expect(parsed_doc.find_all("table").size).to eq(1)
248
248
  end
249
249
  end
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.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-06-04 00:00:00.000000000 Z
11
+ date: 2026-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.7'
19
+ version: '0.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.7'
26
+ version: '0.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -50,6 +50,7 @@ files:
50
50
  - ".gitignore"
51
51
  - ".rubocop.yml"
52
52
  - ".rubocop_todo.yml"
53
+ - CLAUDE.md
53
54
  - CODE_OF_CONDUCT.md
54
55
  - Gemfile
55
56
  - README.adoc
@@ -69,6 +70,7 @@ files:
69
70
  - lib/prosereflect/heading.rb
70
71
  - lib/prosereflect/horizontal_rule.rb
71
72
  - lib/prosereflect/image.rb
73
+ - lib/prosereflect/input.rb
72
74
  - lib/prosereflect/input/html.rb
73
75
  - lib/prosereflect/list_item.rb
74
76
  - lib/prosereflect/mark.rb
@@ -83,6 +85,7 @@ files:
83
85
  - lib/prosereflect/mark/underline.rb
84
86
  - lib/prosereflect/node.rb
85
87
  - lib/prosereflect/ordered_list.rb
88
+ - lib/prosereflect/output.rb
86
89
  - lib/prosereflect/output/html.rb
87
90
  - lib/prosereflect/paragraph.rb
88
91
  - lib/prosereflect/parser.rb
@@ -143,7 +146,6 @@ files:
143
146
  - spec/prosereflect/table_spec.rb
144
147
  - spec/prosereflect/text_spec.rb
145
148
  - spec/prosereflect/user_spec.rb
146
- - spec/prosereflect/version_spec.rb
147
149
  - spec/prosereflect_spec.rb
148
150
  - spec/spec_helper.rb
149
151
  - spec/support/matchers.rb
@@ -155,6 +157,7 @@ metadata:
155
157
  homepage_uri: https://github.com/metanorma/prosereflect
156
158
  source_code_uri: https://github.com/metanorma/prosereflect
157
159
  bug_tracker_uri: https://github.com/metanorma/prosereflect/issues
160
+ rubygems_mfa_required: 'true'
158
161
  post_install_message:
159
162
  rdoc_options: []
160
163
  require_paths:
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe Prosereflect::VERSION do
6
- it 'has a version number' do
7
- expect(Prosereflect::VERSION).not_to be nil
8
- expect(Prosereflect::VERSION).to be_a(String)
9
- expect(Prosereflect::VERSION).to match(/\d+\.\d+\.\d+/)
10
- end
11
- end