oasis-etm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/rake.yml +15 -0
  3. data/.github/workflows/release.yml +23 -0
  4. data/.gitignore +13 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +14 -0
  7. data/.rubocop_todo.yml +24 -0
  8. data/CODE_OF_CONDUCT.md +132 -0
  9. data/Gemfile +15 -0
  10. data/README.adoc +152 -0
  11. data/Rakefile +12 -0
  12. data/bin/console +11 -0
  13. data/bin/setup +8 -0
  14. data/lib/oasis/etm/colspec.rb +28 -0
  15. data/lib/oasis/etm/entry.rb +39 -0
  16. data/lib/oasis/etm/row.rb +22 -0
  17. data/lib/oasis/etm/table.rb +31 -0
  18. data/lib/oasis/etm/tbody.rb +20 -0
  19. data/lib/oasis/etm/tcol.rb +28 -0
  20. data/lib/oasis/etm/tgroup.rb +37 -0
  21. data/lib/oasis/etm/thead.rb +20 -0
  22. data/lib/oasis/etm/version.rb +7 -0
  23. data/lib/oasis/etm.rb +13 -0
  24. data/lib/oasis-etm.rb +1 -0
  25. data/oasis-etm.gemspec +35 -0
  26. data/oasis-etm_wrapped.txt +1910 -0
  27. data/sig/oasis/etm.rbs +6 -0
  28. data/spec/fixtures/isosts/isosts_tables.cals.01.xml +16 -0
  29. data/spec/fixtures/isosts/isosts_tables.cals.02.xml +45 -0
  30. data/spec/fixtures/isosts/isosts_tables.cals.03.xml +35 -0
  31. data/spec/fixtures/isosts/isosts_tables.cals.04.xml +34 -0
  32. data/spec/fixtures/isosts/isosts_tables.cals.05.xml +63 -0
  33. data/spec/fixtures/isosts/isosts_tables.cals.06.xml +52 -0
  34. data/spec/fixtures/isosts/isosts_tables.cals.07.xml +33 -0
  35. data/spec/fixtures/isosts/isosts_tables.cals.08.xml +37 -0
  36. data/spec/fixtures/isosts/isosts_tables.cals.09.xml +37 -0
  37. data/spec/fixtures/isosts/isosts_tables.cals.10.xml +44 -0
  38. data/spec/fixtures/isosts/isosts_tables.cals.11.xml +43 -0
  39. data/spec/fixtures/isosts/isosts_tables.cals.12.xml +22 -0
  40. data/spec/fixtures/native/docbook_example.xml +47 -0
  41. data/spec/fixtures/niso-jats/niso-jats-table-wrap.xml +78 -0
  42. data/spec/oasis/etm/colspec_spec.rb +49 -0
  43. data/spec/oasis/etm/entry_spec.rb +103 -0
  44. data/spec/oasis/etm/row_spec.rb +43 -0
  45. data/spec/oasis/etm/table_spec.rb +94 -0
  46. data/spec/oasis/etm/tbody_spec.rb +48 -0
  47. data/spec/oasis/etm/tgroup_spec.rb +97 -0
  48. data/spec/oasis/etm/thead_spec.rb +48 -0
  49. data/spec/oasis/etm_spec.rb +81 -0
  50. data/spec/spec_helper.rb +31 -0
  51. data/spec/support/shared_examples/validation_examples.rb +20 -0
  52. metadata +110 -0
@@ -0,0 +1,1910 @@
1
+ --- START FILE: .github/workflows/rake.yml ---
2
+ # Auto-generated by Cimas: Do not edit it manually!
3
+ # See https://github.com/metanorma/cimas
4
+ name: rake
5
+
6
+ on:
7
+ push:
8
+ branches: [ master, main ]
9
+ tags: [ v* ]
10
+ pull_request:
11
+
12
+ jobs:
13
+ rake:
14
+ uses: metanorma/ci/.github/workflows/generic-rake.yml@main
15
+ secrets:
16
+ pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }}
17
+ --- END FILE: .github/workflows/rake.yml ---
18
+ --- START FILE: .github/workflows/release.yml ---
19
+ # Auto-generated by Cimas: Do not edit it manually!
20
+ # See https://github.com/metanorma/cimas
21
+ name: release
22
+
23
+ on:
24
+ workflow_dispatch:
25
+ inputs:
26
+ next_version:
27
+ description: |
28
+ Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
29
+ required: true
30
+ default: 'skip'
31
+ repository_dispatch:
32
+ types: [ do-release ]
33
+
34
+ jobs:
35
+ release:
36
+ uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
37
+ with:
38
+ next_version: ${{ github.event.inputs.next_version }}
39
+ secrets:
40
+ rubygems-api-key: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }}
41
+ pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }}
42
+ --- END FILE: .github/workflows/release.yml ---
43
+ --- START FILE: CODE_OF_CONDUCT.md ---
44
+ # Contributor Covenant Code of Conduct
45
+
46
+ ## Our Pledge
47
+
48
+ We as members, contributors, and leaders pledge to make participation in our
49
+ community a harassment-free experience for everyone, regardless of age, body
50
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
51
+ identity and expression, level of experience, education, socio-economic status,
52
+ nationality, personal appearance, race, caste, color, religion, or sexual
53
+ identity and orientation.
54
+
55
+ We pledge to act and interact in ways that contribute to an open, welcoming,
56
+ diverse, inclusive, and healthy community.
57
+
58
+ ## Our Standards
59
+
60
+ Examples of behavior that contributes to a positive environment for our
61
+ community include:
62
+
63
+ * Demonstrating empathy and kindness toward other people
64
+ * Being respectful of differing opinions, viewpoints, and experiences
65
+ * Giving and gracefully accepting constructive feedback
66
+ * Accepting responsibility and apologizing to those affected by our mistakes,
67
+ and learning from the experience
68
+ * Focusing on what is best not just for us as individuals, but for the overall
69
+ community
70
+
71
+ Examples of unacceptable behavior include:
72
+
73
+ * The use of sexualized language or imagery, and sexual attention or advances of
74
+ any kind
75
+ * Trolling, insulting or derogatory comments, and personal or political attacks
76
+ * Public or private harassment
77
+ * Publishing others' private information, such as a physical or email address,
78
+ without their explicit permission
79
+ * Other conduct which could reasonably be considered inappropriate in a
80
+ professional setting
81
+
82
+ ## Enforcement Responsibilities
83
+
84
+ Community leaders are responsible for clarifying and enforcing our standards of
85
+ acceptable behavior and will take appropriate and fair corrective action in
86
+ response to any behavior that they deem inappropriate, threatening, offensive,
87
+ or harmful.
88
+
89
+ Community leaders have the right and responsibility to remove, edit, or reject
90
+ comments, commits, code, wiki edits, issues, and other contributions that are
91
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
92
+ decisions when appropriate.
93
+
94
+ ## Scope
95
+
96
+ This Code of Conduct applies within all community spaces, and also applies when
97
+ an individual is officially representing the community in public spaces.
98
+ Examples of representing our community include using an official email address,
99
+ posting via an official social media account, or acting as an appointed
100
+ representative at an online or offline event.
101
+
102
+ ## Enforcement
103
+
104
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
105
+ reported to the community leaders responsible for enforcement at
106
+ [INSERT CONTACT METHOD].
107
+ All complaints will be reviewed and investigated promptly and fairly.
108
+
109
+ All community leaders are obligated to respect the privacy and security of the
110
+ reporter of any incident.
111
+
112
+ ## Enforcement Guidelines
113
+
114
+ Community leaders will follow these Community Impact Guidelines in determining
115
+ the consequences for any action they deem in violation of this Code of Conduct:
116
+
117
+ ### 1. Correction
118
+
119
+ **Community Impact**: Use of inappropriate language or other behavior deemed
120
+ unprofessional or unwelcome in the community.
121
+
122
+ **Consequence**: A private, written warning from community leaders, providing
123
+ clarity around the nature of the violation and an explanation of why the
124
+ behavior was inappropriate. A public apology may be requested.
125
+
126
+ ### 2. Warning
127
+
128
+ **Community Impact**: A violation through a single incident or series of
129
+ actions.
130
+
131
+ **Consequence**: A warning with consequences for continued behavior. No
132
+ interaction with the people involved, including unsolicited interaction with
133
+ those enforcing the Code of Conduct, for a specified period of time. This
134
+ includes avoiding interactions in community spaces as well as external channels
135
+ like social media. Violating these terms may lead to a temporary or permanent
136
+ ban.
137
+
138
+ ### 3. Temporary Ban
139
+
140
+ **Community Impact**: A serious violation of community standards, including
141
+ sustained inappropriate behavior.
142
+
143
+ **Consequence**: A temporary ban from any sort of interaction or public
144
+ communication with the community for a specified period of time. No public or
145
+ private interaction with the people involved, including unsolicited interaction
146
+ with those enforcing the Code of Conduct, is allowed during this period.
147
+ Violating these terms may lead to a permanent ban.
148
+
149
+ ### 4. Permanent Ban
150
+
151
+ **Community Impact**: Demonstrating a pattern of violation of community
152
+ standards, including sustained inappropriate behavior, harassment of an
153
+ individual, or aggression toward or disparagement of classes of individuals.
154
+
155
+ **Consequence**: A permanent ban from any sort of public interaction within the
156
+ community.
157
+
158
+ ## Attribution
159
+
160
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
161
+ version 2.1, available at
162
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
163
+
164
+ Community Impact Guidelines were inspired by
165
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
166
+
167
+ For answers to common questions about this code of conduct, see the FAQ at
168
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
169
+ [https://www.contributor-covenant.org/translations][translations].
170
+
171
+ [homepage]: https://www.contributor-covenant.org
172
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
173
+ [Mozilla CoC]: https://github.com/mozilla/diversity
174
+ [FAQ]: https://www.contributor-covenant.org/faq
175
+ [translations]: https://www.contributor-covenant.org/translations
176
+ --- END FILE: CODE_OF_CONDUCT.md ---
177
+ --- START FILE: Gemfile ---
178
+ # frozen_string_literal: true
179
+
180
+ source "https://rubygems.org"
181
+
182
+ # Specify your gem's dependencies in oasis-etm.gemspec
183
+ gemspec
184
+
185
+ gem "rake", "~> 13.0"
186
+ gem "rspec", "~> 3.0"
187
+ gem "rubocop", "~> 1.21"
188
+ gem "nokogiri"
189
+ gem "xml-c14n"
190
+ --- END FILE: Gemfile ---
191
+ --- START FILE: README.adoc ---
192
+ = OASIS Exchange Table Model library
193
+
194
+ https://github.com/lutaml/oasis-etm[image:https://img.shields.io/github/stars/lutaml/oasis-etm.svg?style=social[GitHub Stars]]
195
+ https://github.com/lutaml/oasis-etm[image:https://img.shields.io/github/forks/lutaml/oasis-etm.svg?style=social[GitHub Forks]]
196
+ image:https://img.shields.io/github/license/lutaml/oasis-etm.svg[License]
197
+ image:https://img.shields.io/github/actions/workflow/status/lutaml/oasis-etm/test.yml?branch=main[Build Status]
198
+ image:https://img.shields.io/gem/v/oasis-etm.svg[RubyGems Version]
199
+
200
+ == Purpose
201
+
202
+
203
+ == Features
204
+
205
+
206
+ == Installation
207
+
208
+ Add this line to your application's Gemfile:
209
+
210
+ [source,ruby]
211
+ ----
212
+ gem 'oasis-etm'
213
+ ----
214
+
215
+ And then execute:
216
+
217
+ [source,shell]
218
+ ----
219
+ bundle install
220
+ ----
221
+
222
+ Or install it yourself as:
223
+
224
+ [source,shell]
225
+ ----
226
+ gem install oasis-etm
227
+ ----
228
+
229
+ = OASIS Exchange Table Model (ETM) Parser
230
+ :source-highlighter: rouge
231
+ :toc: macro
232
+ :toclevels: 3
233
+
234
+ image:https://img.shields.io/gem/v/oasis-etm.svg[Gem Version, link=https://rubygems.org/gems/oasis-etm]
235
+ image:https://github.com/yourusername/oasis-etm/actions/workflows/test.yml/badge.svg[Build Status, link=https://github.com/yourusername/oasis-etm/actions/workflows/test.yml]
236
+ image:https://img.shields.io/github/license/yourusername/oasis-etm.svg[License, link=https://github.com/yourusername/oasis-etm/blob/main/LICENSE]
237
+
238
+ toc::[]
239
+
240
+ == Purpose
241
+
242
+ Ruby library to parse and create OASIS Exchange Table Model (ETM) formatted tables.
243
+ This library provides a Ruby implementation of the OASIS Technical Resolution TR 9503:1995.
244
+
245
+ == Installation
246
+
247
+ Add this line to your application's Gemfile:
248
+
249
+ [source,ruby]
250
+ ----
251
+ gem 'oasis-etm'
252
+ ----
253
+
254
+ And then execute:
255
+
256
+ [source,sh]
257
+ ----
258
+ $ bundle install
259
+ ----
260
+
261
+ Or install it yourself as:
262
+
263
+ [source,sh]
264
+ ----
265
+ $ gem install oasis-etm
266
+ ----
267
+
268
+
269
+ == Usage
270
+
271
+ === Basic Example
272
+
273
+ [source,ruby]
274
+ ----
275
+ require 'oasis-etm'
276
+
277
+ # Parse an ETM XML file
278
+ table = Oasis::Etm::Table.from_xml(File.read('table.xml'))
279
+
280
+ # Access table attributes
281
+ puts table.frame
282
+ puts table.colsep
283
+ puts table.rowsep
284
+
285
+ # Access table content
286
+ table.tgroups.each do |tgroup|
287
+ tgroup.colspecs.each do |colspec|
288
+ puts "Column #{colspec.colnum}: #{colspec.colwidth}"
289
+ end
290
+ end
291
+
292
+ # Create a new table
293
+ table = Oasis::Etm::Table.new(
294
+ frame: 'all',
295
+ colsep: 1,
296
+ rowsep: 1,
297
+ tgroups: [
298
+ Oasis::Etm::Tgroup.new(
299
+ cols: 3,
300
+ colspecs: [
301
+ Oasis::Etm::Colspec.new(colnum: 1, colwidth: '1*'),
302
+ Oasis::Etm::Colspec.new(colnum: 2, colwidth: '2*'),
303
+ Oasis::Etm::Colspec.new(colnum: 3, colwidth: '1*')
304
+ ]
305
+ )
306
+ ]
307
+ )
308
+
309
+ # Convert to XML
310
+ xml = table.to_xml
311
+ ----
312
+
313
+ === XML Schema
314
+
315
+ The OASIS ETM format follows this basic structure:
316
+
317
+ [source,xml]
318
+ ----
319
+ <table frame="all" colsep="1" rowsep="1">
320
+ <title>Sample Table</title>
321
+ <tgroup cols="3">
322
+ <colspec colnum="1" colwidth="1*"/>
323
+ <colspec colnum="2" colwidth="2*"/>
324
+ <colspec colnum="3" colwidth="1*"/>
325
+ <thead>
326
+ <row>
327
+ <entry>Header 1</entry>
328
+ <entry>Header 2</entry>
329
+ <entry>Header 3</entry>
330
+ </row>
331
+ </thead>
332
+ <tbody>
333
+ <row>
334
+ <entry>Cell 1</entry>
335
+ <entry>Cell 2</entry>
336
+ <entry>Cell 3</entry>
337
+ </row>
338
+ </tbody>
339
+ </tgroup>
340
+ </table>
341
+ ----
342
+
343
+ == Contributing
344
+
345
+ Bug reports and pull requests are welcome. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
346
+
347
+ . Fork it
348
+ . Create your feature branch (`git checkout -b my-new-feature`)
349
+ . Commit your changes (`git commit -am 'Add some feature'`)
350
+ . Push to the branch (`git push origin my-new-feature`)
351
+ . Create new Pull Request
352
+
353
+
354
+ == License and Copyright
355
+
356
+ This project is licensed under the BSD 2-clause License.
357
+ See the link:LICENSE.md[] file for details.
358
+
359
+ Copyright Ribose.
360
+ --- END FILE: README.adoc ---
361
+ --- START FILE: Rakefile ---
362
+ # frozen_string_literal: true
363
+
364
+ require "bundler/gem_tasks"
365
+ require "rspec/core/rake_task"
366
+
367
+ RSpec::Core::RakeTask.new(:spec)
368
+
369
+ require "rubocop/rake_task"
370
+
371
+ RuboCop::RakeTask.new
372
+
373
+ task default: %i[spec rubocop]
374
+ --- END FILE: Rakefile ---
375
+ --- START FILE: lib/oasis-etm.rb ---
376
+ require "oasis/etm"
377
+ --- END FILE: lib/oasis-etm.rb ---
378
+ --- START FILE: lib/oasis/etm.rb ---
379
+ # frozen_string_literal: true
380
+
381
+ require "lutaml/model"
382
+ require_relative "etm/version"
383
+ require_relative "etm/table"
384
+
385
+ module Oasis
386
+ module Etm
387
+ class Error < StandardError; end
388
+
389
+ # Your code goes here...
390
+ end
391
+ end
392
+ --- END FILE: lib/oasis/etm.rb ---
393
+ --- START FILE: lib/oasis/etm/colspec.rb ---
394
+ module Oasis
395
+ module Etm
396
+ class Colspec < Lutaml::Model::Serializable
397
+ # Optional attributes
398
+ attribute :colnum, :integer
399
+ attribute :colname, :string
400
+ attribute :colwidth, :string
401
+ attribute :colsep, :integer, values: [0, 1]
402
+ attribute :rowsep, :integer, values: [0, 1]
403
+ attribute :align, :string, values: %w[left right center justify char]
404
+ attribute :char, :string
405
+ attribute :charoff, :string
406
+
407
+ xml do
408
+ root "colspec"
409
+
410
+ map_attribute "colnum", to: :colnum
411
+ map_attribute "colname", to: :colname
412
+ map_attribute "colwidth", to: :colwidth
413
+ map_attribute "colsep", to: :colsep
414
+ map_attribute "rowsep", to: :rowsep
415
+ map_attribute "align", to: :align
416
+ map_attribute "char", to: :char
417
+ map_attribute "charoff", to: :charoff
418
+ end
419
+ end
420
+ end
421
+ end
422
+ --- END FILE: lib/oasis/etm/colspec.rb ---
423
+ --- START FILE: lib/oasis/etm/entry.rb ---
424
+ module Oasis
425
+ module Etm
426
+ class Entry < Lutaml::Model::Serializable
427
+ # Optional attributes
428
+ attribute :colname, :string
429
+ attribute :namest, :string
430
+ attribute :nameend, :string
431
+ attribute :morerows, :integer
432
+ attribute :colsep, :integer, values: [0, 1]
433
+ attribute :rowsep, :integer, values: [0, 1]
434
+ attribute :align, :string, values: %w[left right center justify char]
435
+ attribute :char, :string
436
+ attribute :charoff, :string
437
+ attribute :valign, :string, values: %w[top middle bottom]
438
+
439
+ # Content
440
+ attribute :content, :string
441
+
442
+ xml do
443
+ root "entry"
444
+
445
+ # Attribute mappings
446
+ map_attribute "colname", to: :colname
447
+ map_attribute "namest", to: :namest
448
+ map_attribute "nameend", to: :nameend
449
+ map_attribute "morerows", to: :morerows
450
+ map_attribute "colsep", to: :colsep
451
+ map_attribute "rowsep", to: :rowsep
452
+ map_attribute "align", to: :align
453
+ map_attribute "char", to: :char
454
+ map_attribute "charoff", to: :charoff
455
+ map_attribute "valign", to: :valign
456
+
457
+ # Content mapping
458
+ map_content to: :content
459
+ end
460
+ end
461
+ end
462
+ end
463
+ --- END FILE: lib/oasis/etm/entry.rb ---
464
+ --- START FILE: lib/oasis/etm/row.rb ---
465
+ require_relative "entry"
466
+
467
+ module Oasis
468
+ module Etm
469
+ class Row < Lutaml::Model::Serializable
470
+ # Optional attributes
471
+ attribute :rowsep, :integer, values: [0, 1]
472
+ attribute :valign, :string, values: %w[top middle bottom]
473
+
474
+ # Content
475
+ attribute :entries, Entry, collection: true
476
+
477
+ xml do
478
+ root "row"
479
+
480
+ map_attribute "rowsep", to: :rowsep
481
+ map_attribute "valign", to: :valign
482
+ map_element "entry", to: :entries
483
+ end
484
+ end
485
+ end
486
+ end
487
+ --- END FILE: lib/oasis/etm/row.rb ---
488
+ --- START FILE: lib/oasis/etm/table.rb ---
489
+ require_relative "tgroup"
490
+
491
+ module Oasis
492
+ module Etm
493
+ class Table < Lutaml::Model::Serializable
494
+ # Table attributes
495
+ attribute :frame, :string, values: %w[top bottom topbot all sides none]
496
+ attribute :colsep, :integer, values: [0, 1]
497
+ attribute :rowsep, :integer, values: [0, 1]
498
+ attribute :pgwide, :integer, values: [0, 1]
499
+
500
+ # Table content
501
+ attribute :title, :string
502
+ attribute :tgroups, Tgroup, collection: true
503
+
504
+ xml do
505
+ root "table"
506
+
507
+ # Frame mappings
508
+ map_attribute "frame", to: :frame
509
+ map_attribute "colsep", to: :colsep
510
+ map_attribute "rowsep", to: :rowsep
511
+ map_attribute "pgwide", to: :pgwide
512
+
513
+ # Content mappings
514
+ map_element "title", to: :title
515
+ map_element "tgroup", to: :tgroups
516
+ end
517
+ end
518
+ end
519
+ end
520
+ --- END FILE: lib/oasis/etm/table.rb ---
521
+ --- START FILE: lib/oasis/etm/tbody.rb ---
522
+ require_relative "row"
523
+
524
+ module Oasis
525
+ module Etm
526
+ class Tbody < Lutaml::Model::Serializable
527
+ # Optional attributes
528
+ attribute :valign, :string, values: %w[top middle bottom]
529
+
530
+ # Content
531
+ attribute :rows, Row, collection: true
532
+
533
+ xml do
534
+ root "tbody"
535
+
536
+ map_attribute "valign", to: :valign
537
+ map_element "row", to: :rows
538
+ end
539
+ end
540
+ end
541
+ end
542
+ --- END FILE: lib/oasis/etm/tbody.rb ---
543
+ --- START FILE: lib/oasis/etm/tcol.rb ---
544
+ module Oasis
545
+ module Etm
546
+ class Colspec < Lutaml::Model::Serializable
547
+ # Optional attributes
548
+ attribute :colnum, :integer
549
+ attribute :colname, :string
550
+ attribute :colwidth, :string
551
+ attribute :colsep, :integer, values: [0, 1]
552
+ attribute :rowsep, :integer, values: [0, 1]
553
+ attribute :align, :string, values: %w[left right center justify char]
554
+ attribute :char, :string
555
+ attribute :charoff, :string
556
+
557
+ xml do
558
+ root "colspec"
559
+
560
+ map_attribute "colnum", to: :colnum
561
+ map_attribute "colname", to: :colname
562
+ map_attribute "colwidth", to: :colwidth
563
+ map_attribute "colsep", to: :colsep
564
+ map_attribute "rowsep", to: :rowsep
565
+ map_attribute "align", to: :align
566
+ map_attribute "char", to: :char
567
+ map_attribute "charoff", to: :charoff
568
+ end
569
+ end
570
+ end
571
+ end
572
+ --- END FILE: lib/oasis/etm/tcol.rb ---
573
+ --- START FILE: lib/oasis/etm/tgroup.rb ---
574
+ require_relative "colspec"
575
+ require_relative "thead"
576
+ require_relative "tbody"
577
+
578
+ module Oasis
579
+ module Etm
580
+ class Tgroup < Lutaml::Model::Serializable
581
+ # Required attributes
582
+ attribute :cols, :integer
583
+
584
+ # Optional attributes
585
+ attribute :colsep, :integer, values: [0, 1]
586
+ attribute :rowsep, :integer, values: [0, 1]
587
+ attribute :align, :string, values: %w[left right center justify char]
588
+
589
+ # Content
590
+ attribute :colspecs, Colspec, collection: true
591
+ attribute :thead, Thead
592
+ attribute :tbody, Tbody
593
+
594
+ xml do
595
+ root "tgroup"
596
+
597
+ # Attribute mappings
598
+ map_attribute "cols", to: :cols
599
+ map_attribute "colsep", to: :colsep
600
+ map_attribute "rowsep", to: :rowsep
601
+ map_attribute "align", to: :align
602
+
603
+ # Content mappings
604
+ map_element "colspec", to: :colspecs
605
+ map_element "thead", to: :thead
606
+ map_element "tbody", to: :tbody
607
+ end
608
+ end
609
+ end
610
+ end
611
+ --- END FILE: lib/oasis/etm/tgroup.rb ---
612
+ --- START FILE: lib/oasis/etm/thead.rb ---
613
+ require_relative "row"
614
+
615
+ module Oasis
616
+ module Etm
617
+ class Thead < Lutaml::Model::Serializable
618
+ # Optional attributes
619
+ attribute :valign, :string, values: %w[top middle bottom]
620
+
621
+ # Content
622
+ attribute :rows, Row, collection: true
623
+
624
+ xml do
625
+ root "thead"
626
+
627
+ map_attribute "valign", to: :valign
628
+ map_element "row", to: :rows
629
+ end
630
+ end
631
+ end
632
+ end
633
+ --- END FILE: lib/oasis/etm/thead.rb ---
634
+ --- START FILE: lib/oasis/etm/version.rb ---
635
+ # frozen_string_literal: true
636
+
637
+ module Oasis
638
+ module Etm
639
+ VERSION = "0.1.0"
640
+ end
641
+ end
642
+ --- END FILE: lib/oasis/etm/version.rb ---
643
+ --- START FILE: oasis-etm.gemspec ---
644
+ # frozen_string_literal: true
645
+
646
+ require_relative "lib/oasis/etm/version"
647
+
648
+ Gem::Specification.new do |spec|
649
+ spec.name = "oasis-etm"
650
+ spec.version = Oasis::Etm::VERSION
651
+ spec.authors = ["Ribose Inc."]
652
+ spec.email = ["open.source@ribose.com"]
653
+
654
+ spec.summary = "Library for OASIS Exchange Table Model"
655
+ spec.description = <<~DESCRIPTION
656
+ Library for manipulation of OASIS Exchange Table Model XML.
657
+ DESCRIPTION
658
+
659
+ spec.homepage = "https://github.com/lutaml/oasis-etm"
660
+ spec.license = "BSD-2-Clause"
661
+
662
+ spec.bindir = "exe"
663
+ spec.require_paths = ["lib"]
664
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
665
+
666
+ # Specify which files should be added to the gem when it is released.
667
+ # The `git ls-files -z` loads the files in the
668
+ # RubyGem that have been added into git.
669
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
670
+ `git ls-files -z`.split("\x0").reject do |f|
671
+ f.match(%r{^(test|features)/})
672
+ end
673
+ end
674
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
675
+
676
+ spec.add_dependency "lutaml-model"
677
+ spec.metadata["rubygems_mfa_required"] = "true"
678
+ end
679
+ --- END FILE: oasis-etm.gemspec ---
680
+ --- START FILE: oasis-etm_wrapped.txt ---
681
+ --- START FILE: .github/workflows/rake.yml ---
682
+ # Auto-generated by Cimas: Do not edit it manually!
683
+ # See https://github.com/metanorma/cimas
684
+ name: rake
685
+
686
+ on:
687
+ push:
688
+ branches: [ master, main ]
689
+ tags: [ v* ]
690
+ pull_request:
691
+
692
+ jobs:
693
+ rake:
694
+ uses: metanorma/ci/.github/workflows/generic-rake.yml@main
695
+ secrets:
696
+ pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }}
697
+ --- END FILE: .github/workflows/rake.yml ---
698
+ --- START FILE: .github/workflows/release.yml ---
699
+ # Auto-generated by Cimas: Do not edit it manually!
700
+ # See https://github.com/metanorma/cimas
701
+ name: release
702
+
703
+ on:
704
+ workflow_dispatch:
705
+ inputs:
706
+ next_version:
707
+ description: |
708
+ Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
709
+ required: true
710
+ default: 'skip'
711
+ repository_dispatch:
712
+ types: [ do-release ]
713
+
714
+ jobs:
715
+ release:
716
+ uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
717
+ with:
718
+ next_version: ${{ github.event.inputs.next_version }}
719
+ secrets:
720
+ rubygems-api-key: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }}
721
+ pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }}
722
+ --- END FILE: .github/workflows/release.yml ---
723
+ --- START FILE: CODE_OF_CONDUCT.md ---
724
+ # Contributor Covenant Code of Conduct
725
+
726
+ ## Our Pledge
727
+
728
+ We as members, contributors, and leaders pledge to make participation in our
729
+ community a harassment-free experience for everyone, regardless of age, body
730
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
731
+ identity and expression, level of experience, education, socio-economic status,
732
+ nationality, personal appearance, race, caste, color, religion, or sexual
733
+ identity and orientation.
734
+
735
+ We pledge to act and interact in ways that contribute to an open, welcoming,
736
+ diverse, inclusive, and healthy community.
737
+
738
+ ## Our Standards
739
+
740
+ Examples of behavior that contributes to a positive environment for our
741
+ community include:
742
+
743
+ * Demonstrating empathy and kindness toward other people
744
+ * Being respectful of differing opinions, viewpoints, and experiences
745
+ * Giving and gracefully accepting constructive feedback
746
+ * Accepting responsibility and apologizing to those affected by our mistakes,
747
+ and learning from the experience
748
+ * Focusing on what is best not just for us as individuals, but for the overall
749
+ community
750
+
751
+ Examples of unacceptable behavior include:
752
+
753
+ * The use of sexualized language or imagery, and sexual attention or advances of
754
+ any kind
755
+ * Trolling, insulting or derogatory comments, and personal or political attacks
756
+ * Public or private harassment
757
+ * Publishing others' private information, such as a physical or email address,
758
+ without their explicit permission
759
+ * Other conduct which could reasonably be considered inappropriate in a
760
+ professional setting
761
+
762
+ ## Enforcement Responsibilities
763
+
764
+ Community leaders are responsible for clarifying and enforcing our standards of
765
+ acceptable behavior and will take appropriate and fair corrective action in
766
+ response to any behavior that they deem inappropriate, threatening, offensive,
767
+ or harmful.
768
+
769
+ Community leaders have the right and responsibility to remove, edit, or reject
770
+ comments, commits, code, wiki edits, issues, and other contributions that are
771
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
772
+ decisions when appropriate.
773
+
774
+ ## Scope
775
+
776
+ This Code of Conduct applies within all community spaces, and also applies when
777
+ an individual is officially representing the community in public spaces.
778
+ Examples of representing our community include using an official email address,
779
+ posting via an official social media account, or acting as an appointed
780
+ representative at an online or offline event.
781
+
782
+ ## Enforcement
783
+
784
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
785
+ reported to the community leaders responsible for enforcement at
786
+ [INSERT CONTACT METHOD].
787
+ All complaints will be reviewed and investigated promptly and fairly.
788
+
789
+ All community leaders are obligated to respect the privacy and security of the
790
+ reporter of any incident.
791
+
792
+ ## Enforcement Guidelines
793
+
794
+ Community leaders will follow these Community Impact Guidelines in determining
795
+ the consequences for any action they deem in violation of this Code of Conduct:
796
+
797
+ ### 1. Correction
798
+
799
+ **Community Impact**: Use of inappropriate language or other behavior deemed
800
+ unprofessional or unwelcome in the community.
801
+
802
+ **Consequence**: A private, written warning from community leaders, providing
803
+ clarity around the nature of the violation and an explanation of why the
804
+ behavior was inappropriate. A public apology may be requested.
805
+
806
+ ### 2. Warning
807
+
808
+ **Community Impact**: A violation through a single incident or series of
809
+ actions.
810
+
811
+ **Consequence**: A warning with consequences for continued behavior. No
812
+ interaction with the people involved, including unsolicited interaction with
813
+ those enforcing the Code of Conduct, for a specified period of time. This
814
+ includes avoiding interactions in community spaces as well as external channels
815
+ like social media. Violating these terms may lead to a temporary or permanent
816
+ ban.
817
+
818
+ ### 3. Temporary Ban
819
+
820
+ **Community Impact**: A serious violation of community standards, including
821
+ sustained inappropriate behavior.
822
+
823
+ **Consequence**: A temporary ban from any sort of interaction or public
824
+ communication with the community for a specified period of time. No public or
825
+ private interaction with the people involved, including unsolicited interaction
826
+ with those enforcing the Code of Conduct, is allowed during this period.
827
+ Violating these terms may lead to a permanent ban.
828
+
829
+ ### 4. Permanent Ban
830
+
831
+ **Community Impact**: Demonstrating a pattern of violation of community
832
+ standards, including sustained inappropriate behavior, harassment of an
833
+ individual, or aggression toward or disparagement of classes of individuals.
834
+
835
+ **Consequence**: A permanent ban from any sort of public interaction within the
836
+ community.
837
+
838
+ ## Attribution
839
+
840
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
841
+ version 2.1, available at
842
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
843
+
844
+ Community Impact Guidelines were inspired by
845
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
846
+
847
+ For answers to common questions about this code of conduct, see the FAQ at
848
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
849
+ [https://www.contributor-covenant.org/translations][translations].
850
+
851
+ [homepage]: https://www.contributor-covenant.org
852
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
853
+ [Mozilla CoC]: https://github.com/mozilla/diversity
854
+ [FAQ]: https://www.contributor-covenant.org/faq
855
+ [translations]: https://www.contributor-covenant.org/translations
856
+ --- END FILE: CODE_OF_CONDUCT.md ---
857
+ --- START FILE: Gemfile ---
858
+ # frozen_string_literal: true
859
+
860
+ source "https://rubygems.org"
861
+
862
+ # Specify your gem's dependencies in oasis-etm.gemspec
863
+ gemspec
864
+
865
+ gem "rake", "~> 13.0"
866
+ gem "rspec", "~> 3.0"
867
+ gem "rubocop", "~> 1.21"
868
+ gem "nokogiri"
869
+ gem "xml-c14n"
870
+ --- END FILE: Gemfile ---
871
+ --- START FILE: README.adoc ---
872
+ = OASIS Exchange Table Model library
873
+
874
+ https://github.com/lutaml/oasis-etm[image:https://img.shields.io/github/stars/lutaml/oasis-etm.svg?style=social[GitHub Stars]]
875
+ https://github.com/lutaml/oasis-etm[image:https://img.shields.io/github/forks/lutaml/oasis-etm.svg?style=social[GitHub Forks]]
876
+ image:https://img.shields.io/github/license/lutaml/oasis-etm.svg[License]
877
+ image:https://img.shields.io/github/actions/workflow/status/lutaml/oasis-etm/test.yml?branch=main[Build Status]
878
+ image:https://img.shields.io/gem/v/oasis-etm.svg[RubyGems Version]
879
+
880
+ == Purpose
881
+
882
+
883
+ == Features
884
+
885
+
886
+ == Installation
887
+
888
+ Add this line to your application's Gemfile:
889
+
890
+ [source,ruby]
891
+ ----
892
+ gem 'oasis-etm'
893
+ ----
894
+
895
+ And then execute:
896
+
897
+ [source,shell]
898
+ ----
899
+ bundle install
900
+ ----
901
+
902
+ Or install it yourself as:
903
+
904
+ [source,shell]
905
+ ----
906
+ gem install oasis-etm
907
+ ----
908
+
909
+ = OASIS Exchange Table Model (ETM) Parser
910
+ :source-highlighter: rouge
911
+ :toc: macro
912
+ :toclevels: 3
913
+
914
+ image:https://img.shields.io/gem/v/oasis-etm.svg[Gem Version, link=https://rubygems.org/gems/oasis-etm]
915
+ image:https://github.com/yourusername/oasis-etm/actions/workflows/test.yml/badge.svg[Build Status, link=https://github.com/yourusername/oasis-etm/actions/workflows/test.yml]
916
+ image:https://img.shields.io/github/license/yourusername/oasis-etm.svg[License, link=https://github.com/yourusername/oasis-etm/blob/main/LICENSE]
917
+
918
+ toc::[]
919
+
920
+ == Purpose
921
+
922
+ Ruby library to parse and create OASIS Exchange Table Model (ETM) formatted tables.
923
+ This library provides a Ruby implementation of the OASIS Technical Resolution TR 9503:1995.
924
+
925
+ == Installation
926
+
927
+ Add this line to your application's Gemfile:
928
+
929
+ [source,ruby]
930
+ ----
931
+ gem 'oasis-etm'
932
+ ----
933
+
934
+ And then execute:
935
+
936
+ [source,sh]
937
+ ----
938
+ $ bundle install
939
+ ----
940
+
941
+ Or install it yourself as:
942
+
943
+ [source,sh]
944
+ ----
945
+ $ gem install oasis-etm
946
+ ----
947
+
948
+
949
+ == Usage
950
+
951
+ === Basic Example
952
+
953
+ [source,ruby]
954
+ ----
955
+ require 'oasis-etm'
956
+
957
+ # Parse an ETM XML file
958
+ table = Oasis::Etm::Table.from_xml(File.read('table.xml'))
959
+
960
+ # Access table attributes
961
+ puts table.frame
962
+ puts table.colsep
963
+ puts table.rowsep
964
+
965
+ # Access table content
966
+ table.tgroups.each do |tgroup|
967
+ tgroup.colspecs.each do |colspec|
968
+ puts "Column #{colspec.colnum}: #{colspec.colwidth}"
969
+ end
970
+ end
971
+
972
+ # Create a new table
973
+ table = Oasis::Etm::Table.new(
974
+ frame: 'all',
975
+ colsep: 1,
976
+ rowsep: 1,
977
+ tgroups: [
978
+ Oasis::Etm::Tgroup.new(
979
+ cols: 3,
980
+ colspecs: [
981
+ Oasis::Etm::Colspec.new(colnum: 1, colwidth: '1*'),
982
+ Oasis::Etm::Colspec.new(colnum: 2, colwidth: '2*'),
983
+ Oasis::Etm::Colspec.new(colnum: 3, colwidth: '1*')
984
+ ]
985
+ )
986
+ ]
987
+ )
988
+
989
+ # Convert to XML
990
+ xml = table.to_xml
991
+ ----
992
+
993
+ === XML Schema
994
+
995
+ The OASIS ETM format follows this basic structure:
996
+
997
+ [source,xml]
998
+ ----
999
+ <table frame="all" colsep="1" rowsep="1">
1000
+ <title>Sample Table</title>
1001
+ <tgroup cols="3">
1002
+ <colspec colnum="1" colwidth="1*"/>
1003
+ <colspec colnum="2" colwidth="2*"/>
1004
+ <colspec colnum="3" colwidth="1*"/>
1005
+ <thead>
1006
+ <row>
1007
+ <entry>Header 1</entry>
1008
+ <entry>Header 2</entry>
1009
+ <entry>Header 3</entry>
1010
+ </row>
1011
+ </thead>
1012
+ <tbody>
1013
+ <row>
1014
+ <entry>Cell 1</entry>
1015
+ <entry>Cell 2</entry>
1016
+ <entry>Cell 3</entry>
1017
+ </row>
1018
+ </tbody>
1019
+ </tgroup>
1020
+ </table>
1021
+ ----
1022
+
1023
+ == Contributing
1024
+
1025
+ Bug reports and pull requests are welcome. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
1026
+
1027
+ . Fork it
1028
+ . Create your feature branch (`git checkout -b my-new-feature`)
1029
+ . Commit your changes (`git commit -am 'Add some feature'`)
1030
+ . Push to the branch (`git push origin my-new-feature`)
1031
+ . Create new Pull Request
1032
+
1033
+
1034
+ == License and Copyright
1035
+
1036
+ This project is licensed under the BSD 2-clause License.
1037
+ See the link:LICENSE.md[] file for details.
1038
+
1039
+ Copyright Ribose.
1040
+ --- END FILE: README.adoc ---
1041
+ --- START FILE: Rakefile ---
1042
+ # frozen_string_literal: true
1043
+
1044
+ require "bundler/gem_tasks"
1045
+ require "rspec/core/rake_task"
1046
+
1047
+ RSpec::Core::RakeTask.new(:spec)
1048
+
1049
+ require "rubocop/rake_task"
1050
+
1051
+ RuboCop::RakeTask.new
1052
+
1053
+ task default: %i[spec rubocop]
1054
+ --- END FILE: Rakefile ---
1055
+ --- START FILE: lib/oasis-etm.rb ---
1056
+ require "oasis/etm"
1057
+ --- END FILE: lib/oasis-etm.rb ---
1058
+ --- START FILE: lib/oasis/etm.rb ---
1059
+ # frozen_string_literal: true
1060
+
1061
+ require "lutaml/model"
1062
+ require_relative "etm/version"
1063
+ require_relative "etm/table"
1064
+
1065
+ module Oasis
1066
+ module Etm
1067
+ class Error < StandardError; end
1068
+
1069
+ # Your code goes here...
1070
+ end
1071
+ end
1072
+ --- END FILE: lib/oasis/etm.rb ---
1073
+ --- START FILE: lib/oasis/etm/colspec.rb ---
1074
+ module Oasis
1075
+ module Etm
1076
+ class Colspec < Lutaml::Model::Serializable
1077
+ # Optional attributes
1078
+ attribute :colnum, :integer
1079
+ attribute :colname, :string
1080
+ attribute :colwidth, :string
1081
+ attribute :colsep, :integer, values: [0, 1]
1082
+ attribute :rowsep, :integer, values: [0, 1]
1083
+ attribute :align, :string, values: %w[left right center justify char]
1084
+ attribute :char, :string
1085
+ attribute :charoff, :string
1086
+
1087
+ xml do
1088
+ root "colspec"
1089
+
1090
+ map_attribute "colnum", to: :colnum
1091
+ map_attribute "colname", to: :colname
1092
+ map_attribute "colwidth", to: :colwidth
1093
+ map_attribute "colsep", to: :colsep
1094
+ map_attribute "rowsep", to: :rowsep
1095
+ map_attribute "align", to: :align
1096
+ map_attribute "char", to: :char
1097
+ map_attribute "charoff", to: :charoff
1098
+ end
1099
+ end
1100
+ end
1101
+ end
1102
+ --- END FILE: lib/oasis/etm/colspec.rb ---
1103
+ --- START FILE: lib/oasis/etm/entry.rb ---
1104
+ module Oasis
1105
+ module Etm
1106
+ class Entry < Lutaml::Model::Serializable
1107
+ # Optional attributes
1108
+ attribute :colname, :string
1109
+ attribute :namest, :string
1110
+ attribute :nameend, :string
1111
+ attribute :morerows, :integer
1112
+ attribute :colsep, :integer, values: [0, 1]
1113
+ attribute :rowsep, :integer, values: [0, 1]
1114
+ attribute :align, :string, values: %w[left right center justify char]
1115
+ attribute :char, :string
1116
+ attribute :charoff, :string
1117
+ attribute :valign, :string, values: %w[top middle bottom]
1118
+
1119
+ # Content
1120
+ attribute :content, :string
1121
+
1122
+ xml do
1123
+ root "entry"
1124
+
1125
+ # Attribute mappings
1126
+ map_attribute "colname", to: :colname
1127
+ map_attribute "namest", to: :namest
1128
+ map_attribute "nameend", to: :nameend
1129
+ map_attribute "morerows", to: :morerows
1130
+ map_attribute "colsep", to: :colsep
1131
+ map_attribute "rowsep", to: :rowsep
1132
+ map_attribute "align", to: :align
1133
+ map_attribute "char", to: :char
1134
+ map_attribute "charoff", to: :charoff
1135
+ map_attribute "valign", to: :valign
1136
+
1137
+ # Content mapping
1138
+ map_content to: :content
1139
+ end
1140
+ end
1141
+ end
1142
+ end
1143
+ --- END FILE: lib/oasis/etm/entry.rb ---
1144
+ --- START FILE: lib/oasis/etm/row.rb ---
1145
+ require_relative "entry"
1146
+
1147
+ module Oasis
1148
+ module Etm
1149
+ class Row < Lutaml::Model::Serializable
1150
+ # Optional attributes
1151
+ attribute :rowsep, :integer, values: [0, 1]
1152
+ attribute :valign, :string, values: %w[top middle bottom]
1153
+
1154
+ # Content
1155
+ attribute :entries, Entry, collection: true
1156
+
1157
+ xml do
1158
+ root "row"
1159
+
1160
+ map_attribute "rowsep", to: :rowsep
1161
+ map_attribute "valign", to: :valign
1162
+ map_element "entry", to: :entries
1163
+ end
1164
+ end
1165
+ end
1166
+ end
1167
+ --- END FILE: lib/oasis/etm/row.rb ---
1168
+ --- START FILE: lib/oasis/etm/table.rb ---
1169
+ require_relative "tgroup"
1170
+
1171
+ module Oasis
1172
+ module Etm
1173
+ class Table < Lutaml::Model::Serializable
1174
+ # Table attributes
1175
+ attribute :frame, :string, values: %w[top bottom topbot all sides none]
1176
+ attribute :colsep, :integer, values: [0, 1]
1177
+ attribute :rowsep, :integer, values: [0, 1]
1178
+ attribute :pgwide, :integer, values: [0, 1]
1179
+
1180
+ # Table content
1181
+ attribute :title, :string
1182
+ attribute :tgroups, Tgroup, collection: true
1183
+
1184
+ xml do
1185
+ root "table"
1186
+
1187
+ # Frame mappings
1188
+ map_attribute "frame", to: :frame
1189
+ map_attribute "colsep", to: :colsep
1190
+ map_attribute "rowsep", to: :rowsep
1191
+ map_attribute "pgwide", to: :pgwide
1192
+
1193
+ # Content mappings
1194
+ map_element "title", to: :title
1195
+ map_element "tgroup", to: :tgroups
1196
+ end
1197
+ end
1198
+ end
1199
+ end
1200
+ --- END FILE: lib/oasis/etm/table.rb ---
1201
+ --- START FILE: lib/oasis/etm/tbody.rb ---
1202
+ require_relative "row"
1203
+
1204
+ module Oasis
1205
+ module Etm
1206
+ class Tbody < Lutaml::Model::Serializable
1207
+ # Optional attributes
1208
+ attribute :valign, :string, values: %w[top middle bottom]
1209
+
1210
+ # Content
1211
+ attribute :rows, Row, collection: true
1212
+
1213
+ xml do
1214
+ root "tbody"
1215
+
1216
+ map_attribute "valign", to: :valign
1217
+ map_element "row", to: :rows
1218
+ end
1219
+ end
1220
+ end
1221
+ end
1222
+ --- END FILE: lib/oasis/etm/tbody.rb ---
1223
+ --- START FILE: lib/oasis/etm/tcol.rb ---
1224
+ module Oasis
1225
+ module Etm
1226
+ class Colspec < Lutaml::Model::Serializable
1227
+ # Optional attributes
1228
+ attribute :colnum, :integer
1229
+ attribute :colname, :string
1230
+ attribute :colwidth, :string
1231
+ attribute :colsep, :integer, values: [0, 1]
1232
+ attribute :rowsep, :integer, values: [0, 1]
1233
+ attribute :align, :string, values: %w[left right center justify char]
1234
+ attribute :char, :string
1235
+ attribute :charoff, :string
1236
+
1237
+ xml do
1238
+ root "colspec"
1239
+
1240
+ map_attribute "colnum", to: :colnum
1241
+ map_attribute "colname", to: :colname
1242
+ map_attribute "colwidth", to: :colwidth
1243
+ map_attribute "colsep", to: :colsep
1244
+ map_attribute "rowsep", to: :rowsep
1245
+ map_attribute "align", to: :align
1246
+ map_attribute "char", to: :char
1247
+ map_attribute "charoff", to: :charoff
1248
+ end
1249
+ end
1250
+ end
1251
+ end
1252
+ --- END FILE: lib/oasis/etm/tcol.rb ---
1253
+ --- START FILE: lib/oasis/etm/tgroup.rb ---
1254
+ require_relative "colspec"
1255
+ require_relative "thead"
1256
+ require_relative "tbody"
1257
+
1258
+ module Oasis
1259
+ module Etm
1260
+ class Tgroup < Lutaml::Model::Serializable
1261
+ # Required attributes
1262
+ attribute :cols, :integer
1263
+
1264
+ # Optional attributes
1265
+ attribute :colsep, :integer, values: [0, 1]
1266
+ attribute :rowsep, :integer, values: [0, 1]
1267
+ attribute :align, :string, values: %w[left right center justify char]
1268
+
1269
+ # Content
1270
+ attribute :colspecs, Colspec, collection: true
1271
+ attribute :thead, Thead
1272
+ attribute :tbody, Tbody
1273
+
1274
+ xml do
1275
+ root "tgroup"
1276
+
1277
+ # Attribute mappings
1278
+ map_attribute "cols", to: :cols
1279
+ map_attribute "colsep", to: :colsep
1280
+ map_attribute "rowsep", to: :rowsep
1281
+ map_attribute "align", to: :align
1282
+
1283
+ # Content mappings
1284
+ map_element "colspec", to: :colspecs
1285
+ map_element "thead", to: :thead
1286
+ map_element "tbody", to: :tbody
1287
+ end
1288
+ end
1289
+ end
1290
+ end
1291
+ --- END FILE: lib/oasis/etm/tgroup.rb ---
1292
+ --- START FILE: lib/oasis/etm/thead.rb ---
1293
+ require_relative "row"
1294
+
1295
+ module Oasis
1296
+ module Etm
1297
+ class Thead < Lutaml::Model::Serializable
1298
+ # Optional attributes
1299
+ attribute :valign, :string, values: %w[top middle bottom]
1300
+
1301
+ # Content
1302
+ attribute :rows, Row, collection: true
1303
+
1304
+ xml do
1305
+ root "thead"
1306
+
1307
+ map_attribute "valign", to: :valign
1308
+ map_element "row", to: :rows
1309
+ end
1310
+ end
1311
+ end
1312
+ end
1313
+ --- END FILE: lib/oasis/etm/thead.rb ---
1314
+ --- START FILE: lib/oasis/etm/version.rb ---
1315
+ # frozen_string_literal: true
1316
+
1317
+ module Oasis
1318
+ module Etm
1319
+ VERSION = "0.1.0"
1320
+ end
1321
+ end
1322
+ --- END FILE: lib/oasis/etm/version.rb ---
1323
+ --- START FILE: oasis-etm.gemspec ---
1324
+ # frozen_string_literal: true
1325
+
1326
+ require_relative "lib/oasis/etm/version"
1327
+
1328
+ Gem::Specification.new do |spec|
1329
+ spec.name = "oasis-etm"
1330
+ spec.version = Oasis::Etm::VERSION
1331
+ spec.authors = ["Ribose Inc."]
1332
+ spec.email = ["open.source@ribose.com"]
1333
+
1334
+ spec.summary = "Library for OASIS Exchange Table Model"
1335
+ spec.description = <<~DESCRIPTION
1336
+ Library for manipulation of OASIS Exchange Table Model XML.
1337
+ DESCRIPTION
1338
+
1339
+ spec.homepage = "https://github.com/lutaml/oasis-etm"
1340
+ spec.license = "BSD-2-Clause"
1341
+
1342
+ spec.bindir = "exe"
1343
+ spec.require_paths = ["lib"]
1344
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
1345
+
1346
+ # Specify which files should be added to the gem when it is released.
1347
+ # The `git ls-files -z` loads the files in the
1348
+ # RubyGem that have been added into git.
1349
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
1350
+ `git ls-files -z`.split("\x0").reject do |f|
1351
+ f.match(%r{^(test|features)/})
1352
+ end
1353
+ end
1354
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
1355
+
1356
+ spec.add_dependency "lutaml-model"
1357
+ spec.metadata["rubygems_mfa_required"] = "true"
1358
+ end
1359
+ --- END FILE: oasis-etm_wrapped.txt ---
1360
+ --- START FILE: sig/oasis/etm.rbs ---
1361
+ module Oasis
1362
+ module Etm
1363
+ VERSION: String
1364
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
1365
+ end
1366
+ end
1367
+ --- END FILE: sig/oasis/etm.rbs ---
1368
+ --- START FILE: spec/oasis/etm/colspec_spec.rb ---
1369
+ RSpec.describe Oasis::Etm::Colspec do
1370
+ let(:xml) do
1371
+ <<~XML
1372
+ <colspec
1373
+ colnum="1"
1374
+ colname="col1"
1375
+ colwidth="1*"
1376
+ colsep="1"
1377
+ rowsep="1"
1378
+ align="center"
1379
+ char="."
1380
+ charoff="50"/>
1381
+ XML
1382
+ end
1383
+
1384
+ describe ".from_xml" do
1385
+ subject(:colspec) { described_class.from_xml(xml) }
1386
+
1387
+ it "parses all attributes" do
1388
+ expect(colspec.colnum).to eq(1)
1389
+ expect(colspec.colname).to eq("col1")
1390
+ expect(colspec.colwidth).to eq("1*")
1391
+ expect(colspec.colsep).to eq(1)
1392
+ expect(colspec.rowsep).to eq(1)
1393
+ expect(colspec.align).to eq("center")
1394
+ expect(colspec.char).to eq(".")
1395
+ expect(colspec.charoff).to eq("50")
1396
+ end
1397
+ end
1398
+
1399
+ describe "#to_xml" do
1400
+ subject(:colspec) do
1401
+ described_class.new(
1402
+ colnum: 1,
1403
+ colname: "col1",
1404
+ colwidth: "1*",
1405
+ colsep: 1,
1406
+ rowsep: 1,
1407
+ align: "center",
1408
+ char: ".",
1409
+ charoff: "50",
1410
+ )
1411
+ end
1412
+
1413
+ it "generates valid XML" do
1414
+ expect(colspec.to_xml).to be_analogous_with(xml)
1415
+ end
1416
+ end
1417
+ end
1418
+ --- END FILE: spec/oasis/etm/colspec_spec.rb ---
1419
+ --- START FILE: spec/oasis/etm/entry_spec.rb ---
1420
+ RSpec.describe Oasis::Etm::Entry do
1421
+ let(:xml) do
1422
+ <<~XML
1423
+ <entry
1424
+ colname="col1"
1425
+ namest="col1"
1426
+ nameend="col2"
1427
+ morerows="1"
1428
+ colsep="1"
1429
+ rowsep="1"
1430
+ align="center"
1431
+ char="."
1432
+ charoff="50"
1433
+ valign="middle">Cell content</entry>
1434
+ XML
1435
+ end
1436
+
1437
+ describe ".from_xml" do
1438
+ subject(:entry) { described_class.from_xml(xml) }
1439
+
1440
+ it "parses attributes" do
1441
+ expect(entry.colname).to eq("col1")
1442
+ expect(entry.namest).to eq("col1")
1443
+ expect(entry.nameend).to eq("col2")
1444
+ expect(entry.morerows).to eq(1)
1445
+ expect(entry.colsep).to eq(1)
1446
+ expect(entry.rowsep).to eq(1)
1447
+ expect(entry.align).to eq("center")
1448
+ expect(entry.char).to eq(".")
1449
+ expect(entry.charoff).to eq("50")
1450
+ expect(entry.valign).to eq("middle")
1451
+ end
1452
+
1453
+ it "parses content" do
1454
+ expect(entry.content).to eq("Cell content")
1455
+ end
1456
+ end
1457
+
1458
+ describe "#to_xml" do
1459
+ subject(:entry) do
1460
+ described_class.new(
1461
+ colname: "col1",
1462
+ namest: "col1",
1463
+ nameend: "col2",
1464
+ morerows: 1,
1465
+ colsep: 1,
1466
+ rowsep: 1,
1467
+ align: "center",
1468
+ char: ".",
1469
+ charoff: "50",
1470
+ valign: "middle",
1471
+ content: "Cell content",
1472
+ )
1473
+ end
1474
+
1475
+ it "generates valid XML" do
1476
+ expect(entry.to_xml).to be_analogous_with(xml)
1477
+ end
1478
+ end
1479
+
1480
+ context "with validation" do
1481
+ it "validates align values" do
1482
+ expect {
1483
+ described_class.new(align: "invalid")
1484
+ }.to raise_error(Lutaml::Model::ValidationError)
1485
+ end
1486
+
1487
+ it "validates valign values" do
1488
+ expect {
1489
+ described_class.new(valign: "invalid")
1490
+ }.to raise_error(Lutaml::Model::ValidationError)
1491
+ end
1492
+
1493
+ it "validates colsep values" do
1494
+ expect {
1495
+ described_class.new(colsep: 2)
1496
+ }.to raise_error(Lutaml::Model::ValidationError)
1497
+ end
1498
+
1499
+ it "validates rowsep values" do
1500
+ expect {
1501
+ described_class.new(rowsep: 2)
1502
+ }.to raise_error(Lutaml::Model::ValidationError)
1503
+ end
1504
+ end
1505
+ end
1506
+ --- END FILE: spec/oasis/etm/entry_spec.rb ---
1507
+ --- START FILE: spec/oasis/etm/row_spec.rb ---
1508
+ RSpec.describe Oasis::Etm::Row do
1509
+ let(:xml) do
1510
+ <<~XML
1511
+ <row rowsep="1" valign="middle">
1512
+ <entry>Cell 1</entry>
1513
+ <entry>Cell 2</entry>
1514
+ <entry>Cell 3</entry>
1515
+ </row>
1516
+ XML
1517
+ end
1518
+
1519
+ describe ".from_xml" do
1520
+ subject(:row) { described_class.from_xml(xml) }
1521
+
1522
+ it "parses attributes" do
1523
+ expect(row.rowsep).to eq(1)
1524
+ expect(row.valign).to eq("middle")
1525
+ end
1526
+
1527
+ it "parses entries" do
1528
+ expect(row.entries.size).to eq(3)
1529
+ expect(row.entries.map(&:content)).to eq(["Cell 1", "Cell 2", "Cell 3"])
1530
+ end
1531
+ end
1532
+
1533
+ describe "#to_xml" do
1534
+ subject(:row) do
1535
+ described_class.new(
1536
+ rowsep: 1,
1537
+ valign: "middle",
1538
+ entries: [
1539
+ Oasis::Etm::Entry.new(content: "Cell 1"),
1540
+ Oasis::Etm::Entry.new(content: "Cell 2"),
1541
+ Oasis::Etm::Entry.new(content: "Cell 3"),
1542
+ ],
1543
+ )
1544
+ end
1545
+
1546
+ it "generates valid XML" do
1547
+ expect(row.to_xml).to be_analogous_with(xml)
1548
+ end
1549
+ end
1550
+ end
1551
+ --- END FILE: spec/oasis/etm/row_spec.rb ---
1552
+ --- START FILE: spec/oasis/etm/table_spec.rb ---
1553
+ RSpec.describe Oasis::Etm::Table do
1554
+ let(:xml) do
1555
+ <<~XML
1556
+ <table frame="all" colsep="1" rowsep="1">
1557
+ <title>Sample Table</title>
1558
+ <tgroup cols="3">
1559
+ <colspec colnum="1" colwidth="1*"/>
1560
+ <colspec colnum="2" colwidth="2*"/>
1561
+ <colspec colnum="3" colwidth="1*"/>
1562
+ <thead>
1563
+ <row>
1564
+ <entry>Header 1</entry>
1565
+ <entry>Header 2</entry>
1566
+ <entry>Header 3</entry>
1567
+ </row>
1568
+ </thead>
1569
+ <tbody>
1570
+ <row>
1571
+ <entry>Cell 1</entry>
1572
+ <entry>Cell 2</entry>
1573
+ <entry>Cell 3</entry>
1574
+ </row>
1575
+ </tbody>
1576
+ </tgroup>
1577
+ </table>
1578
+ XML
1579
+ end
1580
+
1581
+ describe ".from_xml" do
1582
+ subject(:table) { described_class.from_xml(xml) }
1583
+
1584
+ it "parses table attributes" do
1585
+ expect(table.frame).to eq("all")
1586
+ expect(table.colsep).to eq(1)
1587
+ expect(table.rowsep).to eq(1)
1588
+ end
1589
+
1590
+ it "parses title" do
1591
+ expect(table.title).to eq("Sample Table")
1592
+ end
1593
+
1594
+ it "parses tgroup" do
1595
+ expect(table.tgroups.size).to eq(1)
1596
+ expect(table.tgroups.first.cols).to eq(3)
1597
+ end
1598
+ end
1599
+
1600
+ describe "#to_xml" do
1601
+ subject(:table) do
1602
+ described_class.new(
1603
+ frame: "all",
1604
+ colsep: 1,
1605
+ rowsep: 1,
1606
+ title: "Sample Table",
1607
+ tgroups: [
1608
+ Oasis::Etm::Tgroup.new(
1609
+ cols: 3,
1610
+ colspecs: [
1611
+ Oasis::Etm::Colspec.new(colnum: 1, colwidth: "1*"),
1612
+ Oasis::Etm::Colspec.new(colnum: 2, colwidth: "2*"),
1613
+ Oasis::Etm::Colspec.new(colnum: 3, colwidth: "1*"),
1614
+ ],
1615
+ thead: Oasis::Etm::Thead.new(
1616
+ rows: [
1617
+ Oasis::Etm::Row.new(
1618
+ entries: [
1619
+ Oasis::Etm::Entry.new(content: "Header 1"),
1620
+ Oasis::Etm::Entry.new(content: "Header 2"),
1621
+ Oasis::Etm::Entry.new(content: "Header 3"),
1622
+ ],
1623
+ ),
1624
+ ],
1625
+ ),
1626
+ tbody: Oasis::Etm::Tbody.new(
1627
+ rows: [
1628
+ Oasis::Etm::Row.new(
1629
+ entries: [
1630
+ Oasis::Etm::Entry.new(content: "Cell 1"),
1631
+ Oasis::Etm::Entry.new(content: "Cell 2"),
1632
+ Oasis::Etm::Entry.new(content: "Cell 3"),
1633
+ ],
1634
+ ),
1635
+ ],
1636
+ ),
1637
+ ),
1638
+ ],
1639
+ )
1640
+ end
1641
+
1642
+ it "generates valid XML" do
1643
+ expect(table.to_xml).to be_analogous_with(xml)
1644
+ end
1645
+ end
1646
+ end
1647
+ --- END FILE: spec/oasis/etm/table_spec.rb ---
1648
+ --- START FILE: spec/oasis/etm/tbody_spec.rb ---
1649
+ RSpec.describe Oasis::Etm::Tbody do
1650
+ let(:xml) do
1651
+ <<~XML
1652
+ <tbody valign="top">
1653
+ <row>
1654
+ <entry>Cell 1</entry>
1655
+ <entry>Cell 2</entry>
1656
+ <entry>Cell 3</entry>
1657
+ </row>
1658
+ </tbody>
1659
+ XML
1660
+ end
1661
+
1662
+ describe ".from_xml" do
1663
+ subject(:tbody) { described_class.from_xml(xml) }
1664
+
1665
+ it "parses valign attribute" do
1666
+ expect(tbody.valign).to eq("top")
1667
+ end
1668
+
1669
+ it "parses rows" do
1670
+ expect(tbody.rows.size).to eq(1)
1671
+ expect(tbody.rows.first.entries.size).to eq(3)
1672
+ expect(tbody.rows.first.entries.first.content).to eq("Cell 1")
1673
+ end
1674
+ end
1675
+
1676
+ describe "#to_xml" do
1677
+ subject(:tbody) do
1678
+ described_class.new(
1679
+ valign: "top",
1680
+ rows: [
1681
+ Oasis::Etm::Row.new(
1682
+ entries: [
1683
+ Oasis::Etm::Entry.new(content: "Cell 1"),
1684
+ Oasis::Etm::Entry.new(content: "Cell 2"),
1685
+ Oasis::Etm::Entry.new(content: "Cell 3"),
1686
+ ],
1687
+ ),
1688
+ ],
1689
+ )
1690
+ end
1691
+
1692
+ it "generates valid XML" do
1693
+ expect(tbody.to_xml).to be_analogous_with(xml)
1694
+ end
1695
+ end
1696
+ end
1697
+ --- END FILE: spec/oasis/etm/tbody_spec.rb ---
1698
+ --- START FILE: spec/oasis/etm/tgroup_spec.rb ---
1699
+ RSpec.describe Oasis::Etm::Tgroup do
1700
+ let(:xml) do
1701
+ <<~XML
1702
+ <tgroup cols="3" colsep="1" rowsep="1" align="center">
1703
+ <colspec colnum="1" colwidth="1*"/>
1704
+ <colspec colnum="2" colwidth="2*"/>
1705
+ <colspec colnum="3" colwidth="1*"/>
1706
+ <thead>
1707
+ <row>
1708
+ <entry>Header 1</entry>
1709
+ <entry>Header 2</entry>
1710
+ <entry>Header 3</entry>
1711
+ </row>
1712
+ </thead>
1713
+ <tbody>
1714
+ <row>
1715
+ <entry>Cell 1</entry>
1716
+ <entry>Cell 2</entry>
1717
+ <entry>Cell 3</entry>
1718
+ </row>
1719
+ </tbody>
1720
+ </tgroup>
1721
+ XML
1722
+ end
1723
+
1724
+ describe ".from_xml" do
1725
+ subject(:tgroup) { described_class.from_xml(xml) }
1726
+
1727
+ it "parses required attributes" do
1728
+ expect(tgroup.cols).to eq(3)
1729
+ end
1730
+
1731
+ it "parses optional attributes" do
1732
+ expect(tgroup.colsep).to eq(1)
1733
+ expect(tgroup.rowsep).to eq(1)
1734
+ expect(tgroup.align).to eq("center")
1735
+ end
1736
+
1737
+ it "parses colspecs" do
1738
+ expect(tgroup.colspecs.size).to eq(3)
1739
+ expect(tgroup.colspecs.first.colnum).to eq(1)
1740
+ expect(tgroup.colspecs.first.colwidth).to eq("1*")
1741
+ end
1742
+
1743
+ it "parses thead" do
1744
+ expect(tgroup.thead).to be_a(Oasis::Etm::Thead)
1745
+ expect(tgroup.thead.rows.size).to eq(1)
1746
+ end
1747
+
1748
+ it "parses tbody" do
1749
+ expect(tgroup.tbody).to be_a(Oasis::Etm::Tbody)
1750
+ expect(tgroup.tbody.rows.size).to eq(1)
1751
+ end
1752
+ end
1753
+
1754
+ describe "#to_xml" do
1755
+ subject(:tgroup) do
1756
+ described_class.new(
1757
+ cols: 3,
1758
+ colsep: 1,
1759
+ rowsep: 1,
1760
+ align: "center",
1761
+ colspecs: [
1762
+ Oasis::Etm::Colspec.new(colnum: 1, colwidth: "1*"),
1763
+ Oasis::Etm::Colspec.new(colnum: 2, colwidth: "2*"),
1764
+ Oasis::Etm::Colspec.new(colnum: 3, colwidth: "1*"),
1765
+ ],
1766
+ thead: Oasis::Etm::Thead.new(
1767
+ rows: [
1768
+ Oasis::Etm::Row.new(
1769
+ entries: [
1770
+ Oasis::Etm::Entry.new(content: "Header 1"),
1771
+ Oasis::Etm::Entry.new(content: "Header 2"),
1772
+ Oasis::Etm::Entry.new(content: "Header 3"),
1773
+ ],
1774
+ ),
1775
+ ],
1776
+ ),
1777
+ tbody: Oasis::Etm::Tbody.new(
1778
+ rows: [
1779
+ Oasis::Etm::Row.new(
1780
+ entries: [
1781
+ Oasis::Etm::Entry.new(content: "Cell 1"),
1782
+ Oasis::Etm::Entry.new(content: "Cell 2"),
1783
+ Oasis::Etm::Entry.new(content: "Cell 3"),
1784
+ ],
1785
+ ),
1786
+ ],
1787
+ ),
1788
+ )
1789
+ end
1790
+
1791
+ it "generates valid XML" do
1792
+ expect(tgroup.to_xml).to be_analogous_with(xml)
1793
+ end
1794
+ end
1795
+ end
1796
+ --- END FILE: spec/oasis/etm/tgroup_spec.rb ---
1797
+ --- START FILE: spec/oasis/etm/thead_spec.rb ---
1798
+ RSpec.describe Oasis::Etm::Thead do
1799
+ let(:xml) do
1800
+ <<~XML
1801
+ <thead valign="middle">
1802
+ <row>
1803
+ <entry>Header 1</entry>
1804
+ <entry>Header 2</entry>
1805
+ <entry>Header 3</entry>
1806
+ </row>
1807
+ </thead>
1808
+ XML
1809
+ end
1810
+
1811
+ describe ".from_xml" do
1812
+ subject(:thead) { described_class.from_xml(xml) }
1813
+
1814
+ it "parses valign attribute" do
1815
+ expect(thead.valign).to eq("middle")
1816
+ end
1817
+
1818
+ it "parses rows" do
1819
+ expect(thead.rows.size).to eq(1)
1820
+ expect(thead.rows.first.entries.size).to eq(3)
1821
+ expect(thead.rows.first.entries.first.content).to eq("Header 1")
1822
+ end
1823
+ end
1824
+
1825
+ describe "#to_xml" do
1826
+ subject(:thead) do
1827
+ described_class.new(
1828
+ valign: "middle",
1829
+ rows: [
1830
+ Oasis::Etm::Row.new(
1831
+ entries: [
1832
+ Oasis::Etm::Entry.new(content: "Header 1"),
1833
+ Oasis::Etm::Entry.new(content: "Header 2"),
1834
+ Oasis::Etm::Entry.new(content: "Header 3"),
1835
+ ],
1836
+ ),
1837
+ ],
1838
+ )
1839
+ end
1840
+
1841
+ it "generates valid XML" do
1842
+ expect(thead.to_xml).to be_analogous_with(xml)
1843
+ end
1844
+ end
1845
+ end
1846
+ --- END FILE: spec/oasis/etm/thead_spec.rb ---
1847
+ --- START FILE: spec/oasis/etm_spec.rb ---
1848
+ # frozen_string_literal: true
1849
+
1850
+ RSpec.describe Oasis::Etm do
1851
+ it "has a version number" do
1852
+ expect(Oasis::Etm::VERSION).not_to be nil
1853
+ end
1854
+ end
1855
+ --- END FILE: spec/oasis/etm_spec.rb ---
1856
+ --- START FILE: spec/spec_helper.rb ---
1857
+ # frozen_string_literal: true
1858
+
1859
+ require "oasis-etm"
1860
+ require "nokogiri"
1861
+ require "xml-c14n"
1862
+
1863
+ # Require all support files
1864
+ Dir[File.join(__dir__, "support", "**", "*.rb")].sort.each { |f| require f }
1865
+
1866
+ RSpec.configure do |config|
1867
+ # Enable flags like --only-failures and --next-failure
1868
+ config.example_status_persistence_file_path = ".rspec_status"
1869
+
1870
+ # Disable RSpec exposing methods globally on `Module` and `main`
1871
+ config.disable_monkey_patching!
1872
+
1873
+ config.expect_with :rspec do |c|
1874
+ c.syntax = :expect
1875
+ end
1876
+ end
1877
+
1878
+ require "lutaml/model"
1879
+ require "lutaml/model/xml_adapter/nokogiri_adapter"
1880
+ require "lutaml/model/json_adapter/standard_json_adapter"
1881
+ require "lutaml/model/yaml_adapter/standard_yaml_adapter"
1882
+
1883
+ Lutaml::Model::Config.configure do |config|
1884
+ config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
1885
+ config.json_adapter = Lutaml::Model::JsonAdapter::StandardJsonAdapter
1886
+ config.yaml_adapter = Lutaml::Model::YamlAdapter::StandardYamlAdapter
1887
+ end
1888
+ --- END FILE: spec/spec_helper.rb ---
1889
+ --- START FILE: spec/support/shared_examples/validation_examples.rb ---
1890
+ # spec/support/shared_examples/validation_examples.rb
1891
+ RSpec.shared_examples "validates attributes" do |attributes|
1892
+ attributes.each do |attribute, valid_values|
1893
+ context "with #{attribute}" do
1894
+ it "accepts valid values" do
1895
+ valid_values.each do |value|
1896
+ expect {
1897
+ described_class.new(attribute => value)
1898
+ }.not_to raise_error
1899
+ end
1900
+ end
1901
+
1902
+ it "rejects invalid values" do
1903
+ expect {
1904
+ described_class.new(attribute => "invalid")
1905
+ }.to raise_error(Lutaml::Model::ValidationError)
1906
+ end
1907
+ end
1908
+ end
1909
+ end
1910
+ --- END FILE: spec/support/shared_examples/validation_examples.rb ---