metanorma-tools 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.
@@ -0,0 +1,316 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Metanorma::Tools::IsoGraphicFilename do
6
+ # Helper method to create filename objects with common defaults
7
+ def create_filename(**attributes)
8
+ defaults = {
9
+ standard_number: 12345,
10
+ part_number: 1,
11
+ edition_number: 1,
12
+ file_extension: 'dwg'
13
+ }
14
+ described_class.new(defaults.merge(attributes))
15
+ end
16
+
17
+ describe 'ISO DRG Section 3.2 Examples' do
18
+ # Test cases from the README.adoc table
19
+ [
20
+ # Normal figures
21
+ {
22
+ description: 'File for figure 1',
23
+ attributes: { content_type: 'figure', figure_number: '1' },
24
+ expected: '12345-1_ed1fig1.dwg'
25
+ },
26
+ {
27
+ description: 'File for figure 2',
28
+ attributes: { content_type: 'figure', figure_number: '2' },
29
+ expected: '12345-1_ed1fig2.dwg'
30
+ },
31
+
32
+ # Subfigures
33
+ {
34
+ description: 'File for figure 1, subfigure a',
35
+ attributes: { content_type: 'figure', figure_number: '1', subfigure: 'a' },
36
+ expected: '12345-1_ed1fig1a.dwg'
37
+ },
38
+ {
39
+ description: 'File for figure 1, subfigure b',
40
+ attributes: { content_type: 'figure', figure_number: '1', subfigure: 'b' },
41
+ expected: '12345-1_ed1fig1b.dwg'
42
+ },
43
+
44
+ # Figure keys
45
+ {
46
+ description: 'File for figure 1, first key file',
47
+ attributes: { content_type: 'key', figure_number: '1', key_number: 1 },
48
+ expected: '12345-1_ed1fig1_key1.dwg'
49
+ },
50
+ {
51
+ description: 'File for figure 1, second key file',
52
+ attributes: { content_type: 'key', figure_number: '1', key_number: 2 },
53
+ expected: '12345-1_ed1fig1_key2.dwg'
54
+ },
55
+
56
+ # Table figures
57
+ {
58
+ description: 'File for the single figure in Table 1',
59
+ attributes: { content_type: 'table', figure_number: '1' },
60
+ expected: '12345-1_ed1figTab1.dwg'
61
+ },
62
+ {
63
+ description: 'File for the first figure in Table 1',
64
+ attributes: { content_type: 'table', figure_number: '1a' },
65
+ expected: '12345-1_ed1figTab1a.dwg'
66
+ },
67
+ {
68
+ description: 'File for the second figure in Table 1',
69
+ attributes: { content_type: 'table', figure_number: '1b' },
70
+ expected: '12345-1_ed1figTab1b.dwg'
71
+ },
72
+
73
+ # Annex figures
74
+ {
75
+ description: 'File for the first figure in appendix A',
76
+ attributes: { content_type: 'figure', figure_number: 'A1' },
77
+ expected: '12345-1_ed1figA1.dwg'
78
+ },
79
+ {
80
+ description: 'File for the second figure in appendix A',
81
+ attributes: { content_type: 'figure', figure_number: 'A2' },
82
+ expected: '12345-1_ed1figA2.dwg'
83
+ },
84
+ {
85
+ description: 'File for first figure in appendix A, subfigure a',
86
+ attributes: { content_type: 'figure', figure_number: 'A1', subfigure: 'a' },
87
+ expected: '12345-1_ed1figA1a.dwg'
88
+ },
89
+ {
90
+ description: 'File for first figure in appendix A, subfigure b',
91
+ attributes: { content_type: 'figure', figure_number: 'A1', subfigure: 'b' },
92
+ expected: '12345-1_ed1figA1b.dwg'
93
+ },
94
+
95
+ # Language variants
96
+ {
97
+ description: 'File for figure 1, French translation',
98
+ attributes: { content_type: 'figure', figure_number: '1', language_code: 'f' },
99
+ expected: '12345-1_ed1fig1_f.dwg'
100
+ },
101
+
102
+ # Amendments
103
+ {
104
+ description: 'File for figure 1 of amendment 1',
105
+ attributes: { content_type: 'figure', figure_number: '1', supplement_type: 'amd', supplement_number: 1 },
106
+ expected: '12345-1_ed1amd1fig1.dwg'
107
+ },
108
+
109
+ # Inline text graphics
110
+ {
111
+ description: 'File for graphical element inline with text',
112
+ attributes: { content_type: 'text', text_number: 1 },
113
+ expected: '12345-1_ed1figText1.dwg'
114
+ },
115
+
116
+ # Special layout
117
+ {
118
+ description: 'File for table 1 which does not have a figure',
119
+ attributes: { content_type: 'special_layout', table_number: '1' },
120
+ expected: 'SL12345-1_ed1figTab1.dwg'
121
+ }
122
+ ].each do |test_case|
123
+ it test_case[:description] do
124
+ filename = create_filename(**test_case[:attributes])
125
+ expect(filename.to_s).to eq(test_case[:expected])
126
+ end
127
+ end
128
+ end
129
+
130
+ describe 'Additional scenarios' do
131
+ it 'handles complex figure numbers with dots' do
132
+ filename = create_filename(
133
+ content_type: 'figure',
134
+ figure_number: 'A.2',
135
+ file_extension: 'png'
136
+ )
137
+ expect(filename.to_s).to eq('12345-1_ed1figA2.png')
138
+ end
139
+
140
+ it 'handles corrigenda' do
141
+ filename = create_filename(
142
+ part_number: 2,
143
+ supplement_type: 'cor',
144
+ supplement_number: 1,
145
+ content_type: 'figure',
146
+ figure_number: '1'
147
+ )
148
+ expect(filename.to_s).to eq('12345-2_ed1cor1fig1.dwg')
149
+ end
150
+
151
+ it 'handles amendment with stage code' do
152
+ filename = create_filename(
153
+ part_number: 2,
154
+ supplement_type: 'amd',
155
+ supplement_number: 2,
156
+ stage_code: 'fdis',
157
+ content_type: 'figure',
158
+ figure_number: '1'
159
+ )
160
+ expect(filename.to_s).to eq('12345-2_ed1amd2_fdisfig1.dwg')
161
+ end
162
+
163
+ it 'handles different stage codes' do
164
+ %w[pwi np awi wd cd dis fdis prf].each do |stage|
165
+ filename = create_filename(
166
+ stage_code: stage,
167
+ content_type: 'figure',
168
+ figure_number: '1'
169
+ )
170
+ expect(filename.to_s).to eq("12345-1_#{stage}_ed1fig1.dwg")
171
+ end
172
+ end
173
+
174
+ it 'handles all language codes' do
175
+ %w[e f r s a d].each do |lang|
176
+ filename = create_filename(
177
+ content_type: 'figure',
178
+ figure_number: '1',
179
+ language_code: lang
180
+ )
181
+ expect(filename.to_s).to eq("12345-1_ed1fig1_#{lang}.dwg")
182
+ end
183
+ end
184
+
185
+ it 'handles standards without part numbers' do
186
+ filename = create_filename(
187
+ part_number: nil,
188
+ content_type: 'figure',
189
+ figure_number: 'A1',
190
+ file_extension: 'png'
191
+ )
192
+ expect(filename.to_s).to eq('12345_ed1figA1.png')
193
+ end
194
+
195
+ it 'handles different file extensions' do
196
+ %w[svg png jpeg ai eps].each do |ext|
197
+ filename = create_filename(
198
+ content_type: 'figure',
199
+ figure_number: '1',
200
+ file_extension: ext
201
+ )
202
+ expect(filename.to_s).to eq("12345-1_ed1fig1.#{ext}")
203
+ end
204
+ end
205
+
206
+ it 'handles different edition numbers' do
207
+ filename = create_filename(
208
+ edition_number: 3,
209
+ content_type: 'figure',
210
+ figure_number: 'A1',
211
+ file_extension: 'svg'
212
+ )
213
+ expect(filename.to_s).to eq('12345-1_ed3figA1.svg')
214
+ end
215
+ end
216
+
217
+ describe 'original filename preservation' do
218
+ it 'generates extended pattern with original filename' do
219
+ filename = create_filename(
220
+ content_type: 'figure',
221
+ figure_number: '1',
222
+ original_filename: 'diagram-overview.png',
223
+ file_extension: 'png'
224
+ )
225
+ expect(filename.to_s).to eq('12345-1_ed1fig1_diagram-overview.png')
226
+ end
227
+
228
+ it 'strips extension from original filename' do
229
+ filename = create_filename(
230
+ content_type: 'figure',
231
+ figure_number: 'A2',
232
+ subfigure: 'a',
233
+ original_filename: 'flowchart.svg',
234
+ file_extension: 'svg'
235
+ )
236
+ expect(filename.to_s).to eq('12345-1_ed1figA2a_flowchart.svg')
237
+ end
238
+
239
+ it 'handles original filename with language code' do
240
+ filename = create_filename(
241
+ content_type: 'figure',
242
+ figure_number: '3',
243
+ language_code: 'f',
244
+ original_filename: 'schema.png',
245
+ file_extension: 'png'
246
+ )
247
+ expect(filename.to_s).to eq('12345-1_ed1fig3_f_schema.png')
248
+ end
249
+
250
+ it 'handles original filename with complex figure numbers' do
251
+ filename = create_filename(
252
+ content_type: 'figure',
253
+ figure_number: 'C.2',
254
+ subfigure: 'b',
255
+ original_filename: 'c2-b.png',
256
+ file_extension: 'png'
257
+ )
258
+ expect(filename.to_s).to eq('12345-1_ed1figC2b_c2-b.png')
259
+ end
260
+
261
+ it 'ignores empty original filename' do
262
+ filename = create_filename(
263
+ content_type: 'figure',
264
+ figure_number: '1',
265
+ original_filename: '',
266
+ file_extension: 'png'
267
+ )
268
+ expect(filename.to_s).to eq('12345-1_ed1fig1.png')
269
+ end
270
+
271
+ it 'ignores nil original filename' do
272
+ filename = create_filename(
273
+ content_type: 'figure',
274
+ figure_number: '1',
275
+ original_filename: nil,
276
+ file_extension: 'png'
277
+ )
278
+ expect(filename.to_s).to eq('12345-1_ed1fig1.png')
279
+ end
280
+ end
281
+
282
+ describe 'serialization' do
283
+ it 'can be serialized to hash' do
284
+ filename = create_filename(
285
+ stage_code: 'dis',
286
+ content_type: 'figure',
287
+ figure_number: 'A1',
288
+ file_extension: 'png'
289
+ )
290
+
291
+ hash = filename.to_hash
292
+ expect(hash['standard_number']).to eq(12345)
293
+ expect(hash['part_number']).to eq(1)
294
+ expect(hash['stage_code']).to eq('dis')
295
+ expect(hash['edition_number']).to eq(1)
296
+ expect(hash['content_type']).to eq('figure')
297
+ expect(hash['figure_number']).to eq('A1')
298
+ expect(hash['file_extension']).to eq('png')
299
+ end
300
+
301
+ it 'can be created from hash' do
302
+ hash = {
303
+ 'standard_number' => 17301,
304
+ 'part_number' => 1,
305
+ 'stage_code' => 'dis',
306
+ 'edition_number' => 1,
307
+ 'content_type' => 'figure',
308
+ 'figure_number' => 'A1',
309
+ 'file_extension' => 'png'
310
+ }
311
+
312
+ filename = described_class.from_hash(hash)
313
+ expect(filename.to_s).to eq('17301-1_dis_ed1figA1.png')
314
+ end
315
+ end
316
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Metanorma::Tools do
4
+ it "has a version number" do
5
+ expect(Metanorma::Tools::VERSION).not_to be nil
6
+ end
7
+
8
+ it "loads all required classes" do
9
+ expect(Metanorma::Tools::FigureExtractor).to be_a(Class)
10
+ expect(Metanorma::Tools::Figure).to be_a(Class)
11
+ expect(Metanorma::Tools::DocumentMetadata).to be_a(Class)
12
+ expect(Metanorma::Tools::IsoGraphicFilename).to be_a(Class)
13
+ expect(Metanorma::Tools::Cli).to be_a(Class)
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lutaml/model'
4
+ require "metanorma/tools"
5
+
6
+ RSpec.configure do |config|
7
+ # Enable flags like --only-failures and --next-failure
8
+ config.example_status_persistence_file_path = ".rspec_status"
9
+
10
+ # Disable RSpec exposing methods globally on `Module` and `main`
11
+ config.disable_monkey_patching!
12
+
13
+ config.expect_with :rspec do |c|
14
+ c.syntax = :expect
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: metanorma-tools
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-07-03 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
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubyzip
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: thor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: base64
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - open.source@ribose.com
86
+ executables:
87
+ - metanorma-tools
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".github/workflows/rake.yml"
92
+ - ".github/workflows/release.yml"
93
+ - ".gitignore"
94
+ - ".rspec"
95
+ - ".rubocop.yml"
96
+ - CODE_OF_CONDUCT.md
97
+ - Gemfile
98
+ - README.adoc
99
+ - Rakefile
100
+ - docs/figure-extraction.adoc
101
+ - docs/iso-drg-filename-guidance.adoc
102
+ - docs/workflows-iso.adoc
103
+ - exe/metanorma-tools
104
+ - lib/metanorma/tools.rb
105
+ - lib/metanorma/tools/cli.rb
106
+ - lib/metanorma/tools/commands.rb
107
+ - lib/metanorma/tools/commands/extract_images.rb
108
+ - lib/metanorma/tools/document_metadata.rb
109
+ - lib/metanorma/tools/figure.rb
110
+ - lib/metanorma/tools/figure_extractor.rb
111
+ - lib/metanorma/tools/iso_graphic_filename.rb
112
+ - lib/metanorma/tools/version.rb
113
+ - metanorma-tools.gemspec
114
+ - sig/metanorma/tools.rbs
115
+ - spec/fixtures/document-en.dis.presentation.xml
116
+ - spec/metanorma/tools/cli_spec.rb
117
+ - spec/metanorma/tools/document_metadata_spec.rb
118
+ - spec/metanorma/tools/figure_extractor_spec.rb
119
+ - spec/metanorma/tools/iso_graphic_filename_spec.rb
120
+ - spec/metanorma/tools_spec.rb
121
+ - spec/spec_helper.rb
122
+ homepage: https://github.com/metanorma/metanorma-tools
123
+ licenses:
124
+ - BSD-2-Clause
125
+ metadata:
126
+ homepage_uri: https://github.com/metanorma/metanorma-tools
127
+ source_code_uri: https://github.com/metanorma/metanorma-tools
128
+ bug_tracker_uri: https://github.com/metanorma/metanorma-tools/issues
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: 2.6.0
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubygems_version: 3.5.22
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Miscellaneous tools to work with Metanorma output.
148
+ test_files: []