oasis-etm 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad71a9a5219cab7710a57ebe6b3424172a11c50deac97889692b01ac239511a7
4
- data.tar.gz: 11521a92f66914b6afef831dcd34f5544f082a00abc9dbd8e08c00d2ba48a6fc
3
+ metadata.gz: a0ff0a0e066cadfe82cad8a4534d64d06dd4428acf13533a7444fa4b3b5da0d7
4
+ data.tar.gz: 6b67373f1ba6ca859c2b3dd168ec29c4823d9508b6a836aa79574fb9a23e22b0
5
5
  SHA512:
6
- metadata.gz: 6ece8bcbd0b7914cbe9eea7bbc6a9b59c9fc9e88f95f1278a710fa59e13e900239fd5a020c62d9cbfd8412e24664a64b8bf6369e6e73bd047c3a44b4f460ec0a
7
- data.tar.gz: bf7e7b5b1921b33599e1e28ea2b494784227cb07c787dcf7de9a8dbcde5adf84f34f05ac2f97ac09224d375b57d031367960f92fd2abe4543532183d10dca7e3
6
+ metadata.gz: 8f33fffdf217b01fd8c566e5688d98054feace480e47b55f5c35a840f95780011c0771e5f0eb0cf82a1d22d2efca3abaac0e13fd075f917b9f817c84c81282be
7
+ data.tar.gz: a1dd3a44969806db9d390d977d076c2e3dae4d68e4d215f5a5b8eda3342f1423558321db2448254f2af165d10db1716dbb00ef24ee6de8fcb03b19ef001b9930
@@ -13,6 +13,11 @@ on:
13
13
  repository_dispatch:
14
14
  types: [ do-release ]
15
15
 
16
+ permissions:
17
+ contents: write
18
+ packages: write
19
+ id-token: write
20
+
16
21
  jobs:
17
22
  release:
18
23
  uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
data/.gitignore CHANGED
@@ -11,3 +11,5 @@
11
11
 
12
12
  # rspec failure tracking
13
13
  .rspec_status
14
+
15
+ Gemfile.lock
data/.rubocop.yml CHANGED
@@ -1,14 +1,19 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
1
3
  inherit_from:
2
- - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
4
+ - https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
3
5
  - .rubocop_todo.yml
4
6
 
5
- require:
6
- - rubocop-performance
7
- - rubocop-rake
8
- - rubocop-rspec
7
+ inherit_mode:
8
+ merge:
9
+ - Exclude
10
+
11
+ # local repo-specific modifications
12
+ # ...
13
+ plugins:
14
+ - rubocop-rspec
15
+ - rubocop-performance
16
+ - rubocop-rake
9
17
 
10
18
  AllCops:
11
19
  TargetRubyVersion: 3.0
12
- NewCops: enable
13
- Exclude:
14
- - 'vendor/**/*'
data/.rubocop_todo.yml CHANGED
@@ -1,24 +1,46 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2024-11-01 07:12:25 UTC using RuboCop version 1.68.0.
3
+ # on 2026-04-21 10:38:39 UTC using RuboCop version 1.86.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 2
9
+ # Offense count: 1
10
10
  # This cop supports safe autocorrection (--autocorrect).
11
- # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
11
+ # Configuration parameters: EnforcedStyle, IndentationWidth.
12
+ # SupportedStyles: with_first_element, with_fixed_indentation
13
+ Layout/ArrayAlignment:
14
+ Exclude:
15
+ - 'spec/oasis/etm/row_spec.rb'
16
+
17
+ # Offense count: 14
18
+ # This cop supports safe autocorrection (--autocorrect).
19
+ # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
12
20
  # URISchemes: http, https
13
21
  Layout/LineLength:
14
22
  Exclude:
15
23
  - 'spec/oasis/etm/entry_spec.rb'
24
+ - 'spec/oasis/etm/row_spec.rb'
25
+ - 'spec/oasis/etm_spec.rb'
26
+
27
+ # Offense count: 1
28
+ # This cop supports safe autocorrection (--autocorrect).
29
+ # Configuration parameters: AllowInHeredoc.
30
+ Layout/TrailingWhitespace:
31
+ Exclude:
32
+ - 'spec/oasis/etm/row_spec.rb'
16
33
 
17
- # Offense count: 6
34
+ # Offense count: 9
18
35
  # Configuration parameters: CountAsOne.
19
36
  RSpec/ExampleLength:
20
- Max: 10
37
+ Max: 16
21
38
 
22
39
  # Offense count: 12
23
40
  RSpec/MultipleExpectations:
24
41
  Max: 10
42
+
43
+ # Offense count: 3
44
+ # Configuration parameters: AllowedGroups.
45
+ RSpec/NestedGroups:
46
+ Max: 4
data/CLAUDE.md ADDED
@@ -0,0 +1,35 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Commands
6
+
7
+ ```sh
8
+ bundle install # Install dependencies (uses lutaml-model from GitHub main)
9
+ bundle exec rspec # Run all specs
10
+ bundle exec rspec spec/oasis/etm/table_spec.rb # Run a single spec file
11
+ bundle exec rspec spec/oasis/etm/table_spec.rb:30 # Run a single test by line number
12
+ bundle exec rubocop # Lint
13
+ bundle exec rake # Run specs + rubocop (default task)
14
+ ```
15
+
16
+ ## Architecture
17
+
18
+ This gem implements the OASIS Exchange Table Model (TR 9503:1995) as Ruby objects using `lutaml-model` for XML serialization/deserialization.
19
+
20
+ **Core dependency chain:** All models inherit from `Lutaml::Model::Serializable` and share a common `Oasis::Etm::Namespace` definition (canonical URI: `http://docs.oasis-open.org/ns/oasis-exchange/table`, with `uri_aliases` for `urn:oasis:names:tc:xml:table` and the legacy FPI).
21
+
22
+ **Model hierarchy:** `Table` → `Tgroup` → (`Colspec`, `Thead` → `Row` → `Entry`, `Tbody` → `Row` → `Entry`). Each model declares its XML element, namespace, and attribute/element mappings via the `xml do` DSL block.
23
+
24
+ **Key model behaviors:**
25
+ - `colsep`, `rowsep`, `pgwide` attributes accept both integer (`0`/`1`) and legacy SGML string (`"yes"`/`"no"`) values — typed as `:string` with `values: %w[0 1 yes no]`
26
+ - `Entry` uses `mixed_content` and `collection: true` on its `content` attribute for mixed XML content handling
27
+ - `Table` and `Tgroup` use `ordered` to preserve child element ordering
28
+ - The `Namespace` class (subclass of `Lutaml::Xml::Namespace`) defines `uri_aliases` so all three namespace variants parse correctly; serialization always uses the canonical URI
29
+
30
+ **Spec structure:**
31
+ - `spec/oasis/etm/` — unit specs per model (table, entry, tgroup, etc.)
32
+ - `spec/oasis/etm_spec.rb` — round-trip tests using XML fixture files from `spec/fixtures/{native,isosts,niso-jats}/`
33
+ - Round-trip tests use the Canon gem (`be_analogous_with` matcher) with `spec_friendly` profile for XML comparison
34
+ - Some fixtures contain foreign elements (`<bold>`, `<para>`, `<xref>`) removed via Nokogiri before parsing
35
+ - ISOSTS fixtures normalize FPI namespace to URN before comparison (Canon requirement)
data/Gemfile CHANGED
@@ -5,6 +5,8 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in oasis-etm.gemspec
6
6
  gemspec
7
7
 
8
+ gem "canon"
9
+ gem "lutaml-model", github: "lutaml/lutaml-model", branch: "main"
8
10
  gem "nokogiri"
9
11
  gem "rake", "~> 13.0"
10
12
  gem "rspec", "~> 3.0"
@@ -12,4 +14,3 @@ gem "rubocop", "~> 1.21"
12
14
  gem "rubocop-performance"
13
15
  gem "rubocop-rake"
14
16
  gem "rubocop-rspec"
15
- gem "xml-c14n"
data/README.adoc CHANGED
@@ -3,8 +3,8 @@
3
3
  :toclevels: 3
4
4
 
5
5
  image:https://img.shields.io/gem/v/oasis-etm.svg[Gem Version, link=https://rubygems.org/gems/oasis-etm]
6
- 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]
7
- image:https://img.shields.io/github/license/yourusername/oasis-etm.svg[License, link=https://github.com/yourusername/oasis-etm/blob/main/LICENSE]
6
+ image:https://github.com/lutaml/oasis-etm/actions/workflows/test.yml/badge.svg[Build Status, link=https://github.com/lutaml/oasis-etm/actions/workflows/test.yml]
7
+ image:https://img.shields.io/github/license/lutaml/oasis-etm.svg[License, link=https://github.com/lutaml/oasis-etm/blob/main/LICENSE]
8
8
 
9
9
  toc::[]
10
10
 
@@ -16,6 +16,20 @@ exchange. It is used in the DocBook and NISO JATS standards.
16
16
  This library provides a Ruby implementation of the
17
17
  https://www.oasis-open.org/specs/a503.htm[OASIS Technical Resolution TR 9503:1995].
18
18
 
19
+ == Features
20
+
21
+ * Full implementation of the OASIS Exchange Table Model TR 9503:1995
22
+ * Intentionally excludes CALS table features not part of the Exchange subset (like `tfoot`)
23
+ * XML serialization and deserialization
24
+ * Validation of attribute values
25
+ * Support for all Exchange Table Model elements:
26
+ ** `table`
27
+ ** `tgroup`
28
+ ** `colspec`
29
+ ** `thead`
30
+ ** `tbody`
31
+ ** `row`
32
+ ** `entry`
19
33
 
20
34
  == Installation
21
35
 
@@ -115,22 +129,120 @@ The OASIS ETM format follows this basic structure:
115
129
  </table>
116
130
  ----
117
131
 
118
- == Development
132
+ == Round-Trip Conversion Tests
119
133
 
120
- === Test files
134
+ The round-trip tests in `spec/oasis/etm_spec.rb` verify that XML files can be
135
+ parsed into Ruby objects and then serialized back to XML without loss of
136
+ semantic content.
121
137
 
122
- `spec/fixtures/native/docbook_example.xml`::
123
- https://tdg.docbook.org/tdg/4.5/table
138
+ NOTE: These tests use the https://github.com/lutaml/canon[Canon gem] for XML
139
+ comparison with the `spec_friendly` profile, which ignores non-semantic
140
+ differences like attribute ordering and formatting.
124
141
 
125
- `spec/fixtures/niso-jats/niso-jats-table-wrap.xml`::
126
- https://jats.nlm.nih.gov/options/OASIS/tag-library/19990315/element/oasis-table.html
127
- This is to test the OASIS exchange table model when it is namespaced from
128
- another location.
142
+ === Purpose
129
143
 
130
- `spec/fixtures/isosts/isosts_tables.cals.{nn}.xml`::
131
- Tables extracted from https://www.iso.org/schema/isosts/cals/test/isosts_tables.cals.xml.
132
- This is to test the OASIS exchange table model when it is namespaced from
133
- another location.
144
+ Round-trip conversion testing ensures that:
145
+
146
+ * The parser correctly interprets all supported XML elements and attributes
147
+ * The serializer correctly produces XML that preserves semantic meaning
148
+ * The model accurately represents the Exchange Table Model structure
149
+
150
+ === Test Fixtures and Sources
151
+
152
+ The round-trip tests use real-world XML files from various standards:
153
+
154
+ [cols="1,2,3",options="header"]
155
+ |===
156
+ |Fixture |Source |Purpose
157
+
158
+ |`spec/fixtures/native/docbook_example.xml`
159
+ |https://tdg.docbook.org/tdg/4.5/table[DocBook Table Specification]
160
+ |Tests native ETM format (no namespace prefix)
161
+
162
+ |`spec/fixtures/niso-jats/niso-jats-table-wrap.xml`
163
+ |https://jats.nlm.nih.gov/options/OASIS/tag-library/19990315/element/oasis-table.html[NISO JATS Tag Library]
164
+ |Tests ETM with standard OASIS namespace (`http://docs.oasis-open.org/ns/oasis-exchange/table`)
165
+
166
+ |`spec/fixtures/isosts/isosts_tables.cals.{nn}.xml`
167
+ |https://www.iso.org/schema/isosts/cals/test/isosts_tables.cals.xml[ISO ISOSTS Test Suite]
168
+ |Tests ETM with alternative namespace URIs and CALS extensions
169
+ |===
170
+
171
+ === Fixture Oddities
172
+
173
+ The test fixtures contain elements and attributes that are not part of the
174
+ Exchange Table Model specification but appear in real-world documents. The
175
+ round-trip tests handle these as follows:
176
+
177
+ Some fixtures contain elements from other namespaces that the model does not
178
+ support. These are removed before parsing to focus on Exchange Table Model
179
+ compatibility:
180
+
181
+ .Foreign Elements (Removed Before Parsing)
182
+ [cols="2,1"]
183
+ |===
184
+ |Element |Fixture
185
+
186
+ |`+<xref>+` (NISO JATS cross-references)
187
+ |`niso-jats-table-wrap.xml`
188
+
189
+ |`+<para>+` (DocBook paragraph)
190
+ |`docbook_example.xml`
191
+
192
+ |`+<bold>+` (DocBook inline formatting)
193
+ |`isosts_tables.cals.02.xml`
194
+ |===
195
+
196
+ The Exchange Table Model has evolved over time, resulting in multiple namespace
197
+ URIs that refer to the same schema:
198
+
199
+ .Namespace Variants
200
+ [cols="2,1"]
201
+ |===
202
+ |Namespace URI |Used By
203
+
204
+ |`http://docs.oasis-open.org/ns/oasis-exchange/table`
205
+ |Canonical OASIS Exchange Table namespace
206
+
207
+ |`urn:oasis:names:tc:xml:table`
208
+ |ISO ISOSTS format
209
+
210
+ |`-//OASIS//DTD XML Exchange Table Model 19990315//EN`
211
+ |Legacy FPI (Formal Public Identifier) - used as namespace URI in older documents
212
+ |===
213
+
214
+ The model accepts all three namespace variants via `uri_aliases` for parsing.
215
+ When serializing, the model uses the canonical namespace URI for output.
216
+
217
+ The Exchange Table Model predates XML Schema and uses SGML-influenced attribute
218
+ values:
219
+
220
+ .Attribute Value Formats
221
+ [cols="2,1"]
222
+ |===
223
+ |Values |Example
224
+
225
+ |Integers (XML Schema)
226
+ |`colsep="1" rowsep="1"`
227
+
228
+ |Legacy strings (SGML)
229
+ |`colsep="yes" rowsep="no"`
230
+ |===
231
+
232
+ The model accepts both integer (`0`, `1`) and string (`"yes"`, `"no"`) values
233
+ for `colsep`, `rowsep`, and `pgwide` attributes to ensure backward
234
+ compatibility with legacy documents.
235
+
236
+ === Why These Tests Matter
237
+
238
+ Round-trip tests catch regressions that might otherwise go unnoticed:
239
+
240
+ * A missing attribute mapping would cause data loss on serialization
241
+ * An incorrect type coercion would change attribute values
242
+ * Namespace handling bugs would produce invalid XML
243
+ * Changes to element ordering could break downstream consumers
244
+
245
+ By testing with real-world fixtures from established standards, we ensure compatibility with the broader XML table ecosystem.
134
246
 
135
247
 
136
248
  == Contributing
@@ -2,17 +2,22 @@ module Oasis
2
2
  module Etm
3
3
  class Colspec < Lutaml::Model::Serializable
4
4
  # Optional attributes
5
+ # colsep/rowsep accept both integer (0/1) and string ("yes"/"no") values.
6
+ # The string form "yes"/"no" is a legacy SGML representation supported for
7
+ # backward compatibility with older Exchange Table Model documents.
5
8
  attribute :colnum, :integer
6
9
  attribute :colname, :string
7
10
  attribute :colwidth, :string
8
- attribute :colsep, :integer, values: [0, 1]
9
- attribute :rowsep, :integer, values: [0, 1]
11
+ attribute :colsep, :string, values: %w[0 1 yes no]
12
+ attribute :rowsep, :string, values: %w[0 1 yes no]
10
13
  attribute :align, :string, values: %w[left right center justify char]
11
14
  attribute :char, :string
12
15
  attribute :charoff, :string
13
16
 
14
17
  xml do
15
- root "colspec"
18
+ element "colspec"
19
+ namespace Namespace
20
+ ordered
16
21
 
17
22
  map_attribute "colnum", to: :colnum
18
23
  map_attribute "colname", to: :colname
@@ -2,22 +2,27 @@ module Oasis
2
2
  module Etm
3
3
  class Entry < Lutaml::Model::Serializable
4
4
  # Optional attributes
5
+ # colsep/rowsep accept both integer (0/1) and string ("yes"/"no") values.
6
+ # The string form "yes"/"no" is a legacy SGML representation supported for
7
+ # backward compatibility with older Exchange Table Model documents.
5
8
  attribute :colname, :string
6
9
  attribute :namest, :string
7
10
  attribute :nameend, :string
8
11
  attribute :morerows, :integer
9
- attribute :colsep, :integer, values: [0, 1]
10
- attribute :rowsep, :integer, values: [0, 1]
12
+ attribute :colsep, :string, values: %w[0 1 yes no]
13
+ attribute :rowsep, :string, values: %w[0 1 yes no]
11
14
  attribute :align, :string, values: %w[left right center justify char]
12
15
  attribute :char, :string
13
16
  attribute :charoff, :string
14
17
  attribute :valign, :string, values: %w[top middle bottom]
15
18
 
16
19
  # Content
17
- attribute :content, :string
20
+ attribute :content, :string, raw: true, collection: true
18
21
 
19
22
  xml do
20
- root "entry"
23
+ element "entry"
24
+ namespace Namespace
25
+ mixed_content
21
26
 
22
27
  # Attribute mappings
23
28
  map_attribute "colname", to: :colname
@@ -0,0 +1,10 @@
1
+ module Oasis
2
+ module Etm
3
+ class Namespace < Lutaml::Xml::Namespace
4
+ uri "http://docs.oasis-open.org/ns/oasis-exchange/table"
5
+ uri_aliases "urn:oasis:names:tc:xml:table",
6
+ "-//OASIS//DTD XML Exchange Table Model 19990315//EN"
7
+ prefix_default "oasis"
8
+ end
9
+ end
10
+ end
data/lib/oasis/etm/row.rb CHANGED
@@ -1,17 +1,19 @@
1
- require_relative "entry"
2
-
3
1
  module Oasis
4
2
  module Etm
5
3
  class Row < Lutaml::Model::Serializable
6
4
  # Optional attributes
7
- attribute :rowsep, :integer, values: [0, 1]
5
+ # rowsep accepts both integer (0/1) and string ("yes"/"no") values.
6
+ # The string form "yes"/"no" is a legacy SGML representation supported for
7
+ # backward compatibility with older Exchange Table Model documents.
8
+ attribute :rowsep, :string, values: %w[0 1 yes no]
8
9
  attribute :valign, :string, values: %w[top middle bottom]
9
10
 
10
11
  # Content
11
12
  attribute :entries, Entry, collection: true
12
13
 
13
14
  xml do
14
- root "row"
15
+ element "row"
16
+ namespace Namespace
15
17
 
16
18
  map_attribute "rowsep", to: :rowsep
17
19
  map_attribute "valign", to: :valign
@@ -1,20 +1,23 @@
1
- require_relative "tgroup"
2
-
3
1
  module Oasis
4
2
  module Etm
5
3
  class Table < Lutaml::Model::Serializable
6
4
  # Table attributes
5
+ # colsep/rowsep accept both integer (0/1) and string ("yes"/"no") values.
6
+ # The string form "yes"/"no" is a legacy SGML representation supported for
7
+ # backward compatibility with older Exchange Table Model documents.
7
8
  attribute :frame, :string, values: %w[top bottom topbot all sides none]
8
- attribute :colsep, :integer, values: [0, 1]
9
- attribute :rowsep, :integer, values: [0, 1]
10
- attribute :pgwide, :integer, values: [0, 1]
9
+ attribute :colsep, :string, values: %w[0 1 yes no]
10
+ attribute :rowsep, :string, values: %w[0 1 yes no]
11
+ attribute :pgwide, :string, values: %w[0 1 yes no]
11
12
 
12
13
  # Table content
13
14
  attribute :title, :string
14
15
  attribute :tgroups, Tgroup, collection: true
15
16
 
16
17
  xml do
17
- root "table"
18
+ element "table"
19
+ namespace Namespace
20
+ ordered
18
21
 
19
22
  # Frame mappings
20
23
  map_attribute "frame", to: :frame
@@ -1,5 +1,3 @@
1
- require_relative "row"
2
-
3
1
  module Oasis
4
2
  module Etm
5
3
  class Tbody < Lutaml::Model::Serializable
@@ -10,7 +8,8 @@ module Oasis
10
8
  attribute :rows, Row, collection: true
11
9
 
12
10
  xml do
13
- root "tbody"
11
+ element "tbody"
12
+ namespace Namespace
14
13
 
15
14
  map_attribute "valign", to: :valign
16
15
  map_element "row", to: :rows
@@ -2,17 +2,21 @@ module Oasis
2
2
  module Etm
3
3
  class Colspec < Lutaml::Model::Serializable
4
4
  # Optional attributes
5
+ # colsep/rowsep accept both integer (0/1) and string ("yes"/"no") values.
6
+ # The string form "yes"/"no" is a legacy SGML representation supported for
7
+ # backward compatibility with older Exchange Table Model documents.
5
8
  attribute :colnum, :integer
6
9
  attribute :colname, :string
7
10
  attribute :colwidth, :string
8
- attribute :colsep, :integer, values: [0, 1]
9
- attribute :rowsep, :integer, values: [0, 1]
11
+ attribute :colsep, :string, values: %w[0 1 yes no]
12
+ attribute :rowsep, :string, values: %w[0 1 yes no]
10
13
  attribute :align, :string, values: %w[left right center justify char]
11
14
  attribute :char, :string
12
15
  attribute :charoff, :string
13
16
 
14
17
  xml do
15
- root "colspec"
18
+ element "colspec"
19
+ namespace Namespace
16
20
 
17
21
  map_attribute "colnum", to: :colnum
18
22
  map_attribute "colname", to: :colname
@@ -1,7 +1,3 @@
1
- require_relative "colspec"
2
- require_relative "thead"
3
- require_relative "tbody"
4
-
5
1
  module Oasis
6
2
  module Etm
7
3
  class Tgroup < Lutaml::Model::Serializable
@@ -9,8 +5,11 @@ module Oasis
9
5
  attribute :cols, :integer
10
6
 
11
7
  # Optional attributes
12
- attribute :colsep, :integer, values: [0, 1]
13
- attribute :rowsep, :integer, values: [0, 1]
8
+ # colsep/rowsep accept both integer (0/1) and string ("yes"/"no") values.
9
+ # The string form "yes"/"no" is a legacy SGML representation supported for
10
+ # backward compatibility with older Exchange Table Model documents.
11
+ attribute :colsep, :string, values: %w[0 1 yes no]
12
+ attribute :rowsep, :string, values: %w[0 1 yes no]
14
13
  attribute :align, :string, values: %w[left right center justify char]
15
14
 
16
15
  # Content
@@ -19,7 +18,9 @@ module Oasis
19
18
  attribute :tbody, Tbody
20
19
 
21
20
  xml do
22
- root "tgroup"
21
+ element "tgroup"
22
+ namespace Namespace
23
+ ordered
23
24
 
24
25
  # Attribute mappings
25
26
  map_attribute "cols", to: :cols
@@ -1,5 +1,3 @@
1
- require_relative "row"
2
-
3
1
  module Oasis
4
2
  module Etm
5
3
  class Thead < Lutaml::Model::Serializable
@@ -10,7 +8,8 @@ module Oasis
10
8
  attribute :rows, Row, collection: true
11
9
 
12
10
  xml do
13
- root "thead"
11
+ element "thead"
12
+ namespace Namespace
14
13
 
15
14
  map_attribute "valign", to: :valign
16
15
  map_element "row", to: :rows
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Oasis
4
4
  module Etm
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.1"
6
6
  end
7
7
  end
data/lib/oasis/etm.rb CHANGED
@@ -1,13 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "etm/version"
5
- require_relative "etm/table"
6
4
 
7
5
  module Oasis
8
6
  module Etm
9
7
  class Error < StandardError; end
10
8
 
11
- # Your code goes here...
9
+ autoload :Colspec, "oasis/etm/colspec"
10
+ autoload :Entry, "oasis/etm/entry"
11
+ autoload :Namespace, "oasis/etm/namespace"
12
+ autoload :Row, "oasis/etm/row"
13
+ autoload :Table, "oasis/etm/table"
14
+ autoload :Tbody, "oasis/etm/tbody"
15
+ autoload :Colspec, "oasis/etm/tcol"
16
+ autoload :Tgroup, "oasis/etm/tgroup"
17
+ autoload :Thead, "oasis/etm/thead"
18
+ autoload :VERSION, "oasis/etm/version"
12
19
  end
13
20
  end
data/lib/oasis-etm.rb CHANGED
@@ -1 +1,3 @@
1
- require "oasis/etm"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "oasis/etm"
data/oasis-etm.gemspec CHANGED
@@ -30,6 +30,6 @@ Gem::Specification.new do |spec|
30
30
  end
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
32
 
33
- spec.add_dependency "lutaml-model"
33
+ spec.add_dependency "lutaml-model", "~> 0.8.0"
34
34
  spec.metadata["rubygems_mfa_required"] = "true"
35
35
  end
@@ -1,5 +1,6 @@
1
1
  <!-- <!DOCTYPE table PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
2
2
  "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> -->
3
+ <!-- tfoot commented out to comply with ETM (it is a CALS thing -->
3
4
  <table frame='all'><title>Sample Table</title>
4
5
  <tgroup cols='5' align='left' colsep='1' rowsep='1'>
5
6
  <colspec colname='c1'/>
@@ -14,7 +15,7 @@
14
15
  <entry>a5</entry>
15
16
  </row>
16
17
  </thead>
17
- <tfoot>
18
+ <!-- <tfoot>
18
19
  <row>
19
20
  <entry>f1</entry>
20
21
  <entry>f2</entry>
@@ -22,7 +23,7 @@
22
23
  <entry>f4</entry>
23
24
  <entry>f5</entry>
24
25
  </row>
25
- </tfoot>
26
+ </tfoot> -->
26
27
  <tbody>
27
28
  <row>
28
29
  <entry>b1</entry>
@@ -1,7 +1,7 @@
1
1
  RSpec.describe Oasis::Etm::Colspec do
2
2
  let(:xml) do
3
3
  <<~XML
4
- <colspec
4
+ <colspec xmlns="http://docs.oasis-open.org/ns/oasis-exchange/table"
5
5
  colnum="1"
6
6
  colname="col1"
7
7
  colwidth="1*"
@@ -20,8 +20,8 @@ RSpec.describe Oasis::Etm::Colspec do
20
20
  expect(colspec.colnum).to eq(1)
21
21
  expect(colspec.colname).to eq("col1")
22
22
  expect(colspec.colwidth).to eq("1*")
23
- expect(colspec.colsep).to eq(1)
24
- expect(colspec.rowsep).to eq(1)
23
+ expect(colspec.colsep).to eq("1")
24
+ expect(colspec.rowsep).to eq("1")
25
25
  expect(colspec.align).to eq("center")
26
26
  expect(colspec.char).to eq(".")
27
27
  expect(colspec.charoff).to eq("50")
@@ -43,7 +43,7 @@ RSpec.describe Oasis::Etm::Colspec do
43
43
  end
44
44
 
45
45
  it "generates valid XML" do
46
- expect(colspec.to_xml).to be_analogous_with(xml)
46
+ expect(colspec.to_xml).to be_xml_equivalent_to(xml)
47
47
  end
48
48
  end
49
49
  end