From 93a2e5e9142a457a79afcee5ee4cec49cf9deda9 Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Fri, 1 Nov 2024 17:56:31 +0800 Subject: [PATCH] fix: native round-trip specs --- README.adoc | 14 + lib/oasis/etm/entry.rb | 2 +- lib/oasis/etm/table.rb | 2 +- lib/oasis/etm/tgroup.rb | 2 +- oasis-etm_wrapped.txt | 1910 ---------------------- spec/fixtures/native/docbook_example.xml | 5 +- 6 files changed, 20 insertions(+), 1915 deletions(-) delete mode 100644 oasis-etm_wrapped.txt diff --git a/README.adoc b/README.adoc index fb30767..c81542c 100644 --- a/README.adoc +++ b/README.adoc @@ -16,6 +16,20 @@ exchange. It is used in the DocBook and NISO JATS standards. This library provides a Ruby implementation of the https://www.oasis-open.org/specs/a503.htm[OASIS Technical Resolution TR 9503:1995]. +== Features + +* Full implementation of the OASIS Exchange Table Model TR 9503:1995 +* Intentionally excludes CALS table features not part of the Exchange subset (like `tfoot`) +* XML serialization and deserialization +* Validation of attribute values +* Support for all Exchange Table Model elements: +** `table` +** `tgroup` +** `colspec` +** `thead` +** `tbody` +** `row` +** `entry` == Installation diff --git a/lib/oasis/etm/entry.rb b/lib/oasis/etm/entry.rb index 83cd9af..a527614 100644 --- a/lib/oasis/etm/entry.rb +++ b/lib/oasis/etm/entry.rb @@ -14,7 +14,7 @@ class Entry < Lutaml::Model::Serializable attribute :valign, :string, values: %w[top middle bottom] # Content - attribute :content, :string + attribute :content, :string, raw: true xml do root "entry" diff --git a/lib/oasis/etm/table.rb b/lib/oasis/etm/table.rb index 5bdcb2b..9ee177b 100644 --- a/lib/oasis/etm/table.rb +++ b/lib/oasis/etm/table.rb @@ -14,7 +14,7 @@ class Table < Lutaml::Model::Serializable attribute :tgroups, Tgroup, collection: true xml do - root "table" + root "table", ordered: true # Frame mappings map_attribute "frame", to: :frame diff --git a/lib/oasis/etm/tgroup.rb b/lib/oasis/etm/tgroup.rb index 1893560..d9a7cde 100644 --- a/lib/oasis/etm/tgroup.rb +++ b/lib/oasis/etm/tgroup.rb @@ -19,7 +19,7 @@ class Tgroup < Lutaml::Model::Serializable attribute :tbody, Tbody xml do - root "tgroup" + root "tgroup", ordered: true # Attribute mappings map_attribute "cols", to: :cols diff --git a/oasis-etm_wrapped.txt b/oasis-etm_wrapped.txt deleted file mode 100644 index c36ecb7..0000000 --- a/oasis-etm_wrapped.txt +++ /dev/null @@ -1,1910 +0,0 @@ ---- START FILE: .github/workflows/rake.yml --- -# Auto-generated by Cimas: Do not edit it manually! -# See https://github.com/metanorma/cimas -name: rake - -on: - push: - branches: [ master, main ] - tags: [ v* ] - pull_request: - -jobs: - rake: - uses: metanorma/ci/.github/workflows/generic-rake.yml@main - secrets: - pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }} ---- END FILE: .github/workflows/rake.yml --- ---- START FILE: .github/workflows/release.yml --- -# Auto-generated by Cimas: Do not edit it manually! -# See https://github.com/metanorma/cimas -name: release - -on: - workflow_dispatch: - inputs: - next_version: - description: | - Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc - required: true - default: 'skip' - repository_dispatch: - types: [ do-release ] - -jobs: - release: - uses: metanorma/ci/.github/workflows/rubygems-release.yml@main - with: - next_version: ${{ github.event.inputs.next_version }} - secrets: - rubygems-api-key: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }} - pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }} ---- END FILE: .github/workflows/release.yml --- ---- START FILE: CODE_OF_CONDUCT.md --- -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, caste, color, religion, or sexual -identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the overall - community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or advances of - any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email address, - without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official email address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -[INSERT CONTACT METHOD]. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of -actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or permanent -ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the -community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.1, available at -[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. - -Community Impact Guidelines were inspired by -[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. - -For answers to common questions about this code of conduct, see the FAQ at -[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at -[https://www.contributor-covenant.org/translations][translations]. - -[homepage]: https://www.contributor-covenant.org -[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html -[Mozilla CoC]: https://github.com/mozilla/diversity -[FAQ]: https://www.contributor-covenant.org/faq -[translations]: https://www.contributor-covenant.org/translations ---- END FILE: CODE_OF_CONDUCT.md --- ---- START FILE: Gemfile --- -# frozen_string_literal: true - -source "https://rubygems.org" - -# Specify your gem's dependencies in oasis-etm.gemspec -gemspec - -gem "rake", "~> 13.0" -gem "rspec", "~> 3.0" -gem "rubocop", "~> 1.21" -gem "nokogiri" -gem "xml-c14n" ---- END FILE: Gemfile --- ---- START FILE: README.adoc --- -= OASIS Exchange Table Model library - -https://github.com/lutaml/oasis-etm[image:https://img.shields.io/github/stars/lutaml/oasis-etm.svg?style=social[GitHub Stars]] -https://github.com/lutaml/oasis-etm[image:https://img.shields.io/github/forks/lutaml/oasis-etm.svg?style=social[GitHub Forks]] -image:https://img.shields.io/github/license/lutaml/oasis-etm.svg[License] -image:https://img.shields.io/github/actions/workflow/status/lutaml/oasis-etm/test.yml?branch=main[Build Status] -image:https://img.shields.io/gem/v/oasis-etm.svg[RubyGems Version] - -== Purpose - - -== Features - - -== Installation - -Add this line to your application's Gemfile: - -[source,ruby] ----- -gem 'oasis-etm' ----- - -And then execute: - -[source,shell] ----- -bundle install ----- - -Or install it yourself as: - -[source,shell] ----- -gem install oasis-etm ----- - -= OASIS Exchange Table Model (ETM) Parser -:source-highlighter: rouge -:toc: macro -:toclevels: 3 - -image:https://img.shields.io/gem/v/oasis-etm.svg[Gem Version, link=https://rubygems.org/gems/oasis-etm] -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] -image:https://img.shields.io/github/license/yourusername/oasis-etm.svg[License, link=https://github.com/yourusername/oasis-etm/blob/main/LICENSE] - -toc::[] - -== Purpose - -Ruby library to parse and create OASIS Exchange Table Model (ETM) formatted tables. -This library provides a Ruby implementation of the OASIS Technical Resolution TR 9503:1995. - -== Installation - -Add this line to your application's Gemfile: - -[source,ruby] ----- -gem 'oasis-etm' ----- - -And then execute: - -[source,sh] ----- -$ bundle install ----- - -Or install it yourself as: - -[source,sh] ----- -$ gem install oasis-etm ----- - - -== Usage - -=== Basic Example - -[source,ruby] ----- -require 'oasis-etm' - -# Parse an ETM XML file -table = Oasis::Etm::Table.from_xml(File.read('table.xml')) - -# Access table attributes -puts table.frame -puts table.colsep -puts table.rowsep - -# Access table content -table.tgroups.each do |tgroup| - tgroup.colspecs.each do |colspec| - puts "Column #{colspec.colnum}: #{colspec.colwidth}" - end -end - -# Create a new table -table = Oasis::Etm::Table.new( - frame: 'all', - colsep: 1, - rowsep: 1, - tgroups: [ - Oasis::Etm::Tgroup.new( - cols: 3, - colspecs: [ - Oasis::Etm::Colspec.new(colnum: 1, colwidth: '1*'), - Oasis::Etm::Colspec.new(colnum: 2, colwidth: '2*'), - Oasis::Etm::Colspec.new(colnum: 3, colwidth: '1*') - ] - ) - ] -) - -# Convert to XML -xml = table.to_xml ----- - -=== XML Schema - -The OASIS ETM format follows this basic structure: - -[source,xml] ----- - - Sample Table - - - - - - - Header 1 - Header 2 - Header 3 - - - - - Cell 1 - Cell 2 - Cell 3 - - - -
----- - -== Contributing - -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. - -. Fork it -. Create your feature branch (`git checkout -b my-new-feature`) -. Commit your changes (`git commit -am 'Add some feature'`) -. Push to the branch (`git push origin my-new-feature`) -. Create new Pull Request - - -== License and Copyright - -This project is licensed under the BSD 2-clause License. -See the link:LICENSE.md[] file for details. - -Copyright Ribose. ---- END FILE: README.adoc --- ---- START FILE: Rakefile --- -# frozen_string_literal: true - -require "bundler/gem_tasks" -require "rspec/core/rake_task" - -RSpec::Core::RakeTask.new(:spec) - -require "rubocop/rake_task" - -RuboCop::RakeTask.new - -task default: %i[spec rubocop] ---- END FILE: Rakefile --- ---- START FILE: lib/oasis-etm.rb --- -require "oasis/etm" ---- END FILE: lib/oasis-etm.rb --- ---- START FILE: lib/oasis/etm.rb --- -# frozen_string_literal: true - -require "lutaml/model" -require_relative "etm/version" -require_relative "etm/table" - -module Oasis - module Etm - class Error < StandardError; end - - # Your code goes here... - end -end ---- END FILE: lib/oasis/etm.rb --- ---- START FILE: lib/oasis/etm/colspec.rb --- -module Oasis - module Etm - class Colspec < Lutaml::Model::Serializable - # Optional attributes - attribute :colnum, :integer - attribute :colname, :string - attribute :colwidth, :string - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :align, :string, values: %w[left right center justify char] - attribute :char, :string - attribute :charoff, :string - - xml do - root "colspec" - - map_attribute "colnum", to: :colnum - map_attribute "colname", to: :colname - map_attribute "colwidth", to: :colwidth - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "align", to: :align - map_attribute "char", to: :char - map_attribute "charoff", to: :charoff - end - end - end -end ---- END FILE: lib/oasis/etm/colspec.rb --- ---- START FILE: lib/oasis/etm/entry.rb --- -module Oasis - module Etm - class Entry < Lutaml::Model::Serializable - # Optional attributes - attribute :colname, :string - attribute :namest, :string - attribute :nameend, :string - attribute :morerows, :integer - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :align, :string, values: %w[left right center justify char] - attribute :char, :string - attribute :charoff, :string - attribute :valign, :string, values: %w[top middle bottom] - - # Content - attribute :content, :string - - xml do - root "entry" - - # Attribute mappings - map_attribute "colname", to: :colname - map_attribute "namest", to: :namest - map_attribute "nameend", to: :nameend - map_attribute "morerows", to: :morerows - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "align", to: :align - map_attribute "char", to: :char - map_attribute "charoff", to: :charoff - map_attribute "valign", to: :valign - - # Content mapping - map_content to: :content - end - end - end -end ---- END FILE: lib/oasis/etm/entry.rb --- ---- START FILE: lib/oasis/etm/row.rb --- -require_relative "entry" - -module Oasis - module Etm - class Row < Lutaml::Model::Serializable - # Optional attributes - attribute :rowsep, :integer, values: [0, 1] - attribute :valign, :string, values: %w[top middle bottom] - - # Content - attribute :entries, Entry, collection: true - - xml do - root "row" - - map_attribute "rowsep", to: :rowsep - map_attribute "valign", to: :valign - map_element "entry", to: :entries - end - end - end -end ---- END FILE: lib/oasis/etm/row.rb --- ---- START FILE: lib/oasis/etm/table.rb --- -require_relative "tgroup" - -module Oasis - module Etm - class Table < Lutaml::Model::Serializable - # Table attributes - attribute :frame, :string, values: %w[top bottom topbot all sides none] - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :pgwide, :integer, values: [0, 1] - - # Table content - attribute :title, :string - attribute :tgroups, Tgroup, collection: true - - xml do - root "table" - - # Frame mappings - map_attribute "frame", to: :frame - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "pgwide", to: :pgwide - - # Content mappings - map_element "title", to: :title - map_element "tgroup", to: :tgroups - end - end - end -end ---- END FILE: lib/oasis/etm/table.rb --- ---- START FILE: lib/oasis/etm/tbody.rb --- -require_relative "row" - -module Oasis - module Etm - class Tbody < Lutaml::Model::Serializable - # Optional attributes - attribute :valign, :string, values: %w[top middle bottom] - - # Content - attribute :rows, Row, collection: true - - xml do - root "tbody" - - map_attribute "valign", to: :valign - map_element "row", to: :rows - end - end - end -end ---- END FILE: lib/oasis/etm/tbody.rb --- ---- START FILE: lib/oasis/etm/tcol.rb --- -module Oasis - module Etm - class Colspec < Lutaml::Model::Serializable - # Optional attributes - attribute :colnum, :integer - attribute :colname, :string - attribute :colwidth, :string - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :align, :string, values: %w[left right center justify char] - attribute :char, :string - attribute :charoff, :string - - xml do - root "colspec" - - map_attribute "colnum", to: :colnum - map_attribute "colname", to: :colname - map_attribute "colwidth", to: :colwidth - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "align", to: :align - map_attribute "char", to: :char - map_attribute "charoff", to: :charoff - end - end - end -end ---- END FILE: lib/oasis/etm/tcol.rb --- ---- START FILE: lib/oasis/etm/tgroup.rb --- -require_relative "colspec" -require_relative "thead" -require_relative "tbody" - -module Oasis - module Etm - class Tgroup < Lutaml::Model::Serializable - # Required attributes - attribute :cols, :integer - - # Optional attributes - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :align, :string, values: %w[left right center justify char] - - # Content - attribute :colspecs, Colspec, collection: true - attribute :thead, Thead - attribute :tbody, Tbody - - xml do - root "tgroup" - - # Attribute mappings - map_attribute "cols", to: :cols - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "align", to: :align - - # Content mappings - map_element "colspec", to: :colspecs - map_element "thead", to: :thead - map_element "tbody", to: :tbody - end - end - end -end ---- END FILE: lib/oasis/etm/tgroup.rb --- ---- START FILE: lib/oasis/etm/thead.rb --- -require_relative "row" - -module Oasis - module Etm - class Thead < Lutaml::Model::Serializable - # Optional attributes - attribute :valign, :string, values: %w[top middle bottom] - - # Content - attribute :rows, Row, collection: true - - xml do - root "thead" - - map_attribute "valign", to: :valign - map_element "row", to: :rows - end - end - end -end ---- END FILE: lib/oasis/etm/thead.rb --- ---- START FILE: lib/oasis/etm/version.rb --- -# frozen_string_literal: true - -module Oasis - module Etm - VERSION = "0.1.0" - end -end ---- END FILE: lib/oasis/etm/version.rb --- ---- START FILE: oasis-etm.gemspec --- -# frozen_string_literal: true - -require_relative "lib/oasis/etm/version" - -Gem::Specification.new do |spec| - spec.name = "oasis-etm" - spec.version = Oasis::Etm::VERSION - spec.authors = ["Ribose Inc."] - spec.email = ["open.source@ribose.com"] - - spec.summary = "Library for OASIS Exchange Table Model" - spec.description = <<~DESCRIPTION - Library for manipulation of OASIS Exchange Table Model XML. - DESCRIPTION - - spec.homepage = "https://github.com/lutaml/oasis-etm" - spec.license = "BSD-2-Clause" - - spec.bindir = "exe" - spec.require_paths = ["lib"] - spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0") - - # Specify which files should be added to the gem when it is released. - # The `git ls-files -z` loads the files in the - # RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path(__dir__)) do - `git ls-files -z`.split("\x0").reject do |f| - f.match(%r{^(test|features)/}) - end - end - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - - spec.add_dependency "lutaml-model" - spec.metadata["rubygems_mfa_required"] = "true" -end ---- END FILE: oasis-etm.gemspec --- ---- START FILE: oasis-etm_wrapped.txt --- ---- START FILE: .github/workflows/rake.yml --- -# Auto-generated by Cimas: Do not edit it manually! -# See https://github.com/metanorma/cimas -name: rake - -on: - push: - branches: [ master, main ] - tags: [ v* ] - pull_request: - -jobs: - rake: - uses: metanorma/ci/.github/workflows/generic-rake.yml@main - secrets: - pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }} ---- END FILE: .github/workflows/rake.yml --- ---- START FILE: .github/workflows/release.yml --- -# Auto-generated by Cimas: Do not edit it manually! -# See https://github.com/metanorma/cimas -name: release - -on: - workflow_dispatch: - inputs: - next_version: - description: | - Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc - required: true - default: 'skip' - repository_dispatch: - types: [ do-release ] - -jobs: - release: - uses: metanorma/ci/.github/workflows/rubygems-release.yml@main - with: - next_version: ${{ github.event.inputs.next_version }} - secrets: - rubygems-api-key: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }} - pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }} ---- END FILE: .github/workflows/release.yml --- ---- START FILE: CODE_OF_CONDUCT.md --- -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, caste, color, religion, or sexual -identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the overall - community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or advances of - any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email address, - without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official email address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -[INSERT CONTACT METHOD]. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of -actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or permanent -ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the -community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.1, available at -[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. - -Community Impact Guidelines were inspired by -[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. - -For answers to common questions about this code of conduct, see the FAQ at -[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at -[https://www.contributor-covenant.org/translations][translations]. - -[homepage]: https://www.contributor-covenant.org -[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html -[Mozilla CoC]: https://github.com/mozilla/diversity -[FAQ]: https://www.contributor-covenant.org/faq -[translations]: https://www.contributor-covenant.org/translations ---- END FILE: CODE_OF_CONDUCT.md --- ---- START FILE: Gemfile --- -# frozen_string_literal: true - -source "https://rubygems.org" - -# Specify your gem's dependencies in oasis-etm.gemspec -gemspec - -gem "rake", "~> 13.0" -gem "rspec", "~> 3.0" -gem "rubocop", "~> 1.21" -gem "nokogiri" -gem "xml-c14n" ---- END FILE: Gemfile --- ---- START FILE: README.adoc --- -= OASIS Exchange Table Model library - -https://github.com/lutaml/oasis-etm[image:https://img.shields.io/github/stars/lutaml/oasis-etm.svg?style=social[GitHub Stars]] -https://github.com/lutaml/oasis-etm[image:https://img.shields.io/github/forks/lutaml/oasis-etm.svg?style=social[GitHub Forks]] -image:https://img.shields.io/github/license/lutaml/oasis-etm.svg[License] -image:https://img.shields.io/github/actions/workflow/status/lutaml/oasis-etm/test.yml?branch=main[Build Status] -image:https://img.shields.io/gem/v/oasis-etm.svg[RubyGems Version] - -== Purpose - - -== Features - - -== Installation - -Add this line to your application's Gemfile: - -[source,ruby] ----- -gem 'oasis-etm' ----- - -And then execute: - -[source,shell] ----- -bundle install ----- - -Or install it yourself as: - -[source,shell] ----- -gem install oasis-etm ----- - -= OASIS Exchange Table Model (ETM) Parser -:source-highlighter: rouge -:toc: macro -:toclevels: 3 - -image:https://img.shields.io/gem/v/oasis-etm.svg[Gem Version, link=https://rubygems.org/gems/oasis-etm] -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] -image:https://img.shields.io/github/license/yourusername/oasis-etm.svg[License, link=https://github.com/yourusername/oasis-etm/blob/main/LICENSE] - -toc::[] - -== Purpose - -Ruby library to parse and create OASIS Exchange Table Model (ETM) formatted tables. -This library provides a Ruby implementation of the OASIS Technical Resolution TR 9503:1995. - -== Installation - -Add this line to your application's Gemfile: - -[source,ruby] ----- -gem 'oasis-etm' ----- - -And then execute: - -[source,sh] ----- -$ bundle install ----- - -Or install it yourself as: - -[source,sh] ----- -$ gem install oasis-etm ----- - - -== Usage - -=== Basic Example - -[source,ruby] ----- -require 'oasis-etm' - -# Parse an ETM XML file -table = Oasis::Etm::Table.from_xml(File.read('table.xml')) - -# Access table attributes -puts table.frame -puts table.colsep -puts table.rowsep - -# Access table content -table.tgroups.each do |tgroup| - tgroup.colspecs.each do |colspec| - puts "Column #{colspec.colnum}: #{colspec.colwidth}" - end -end - -# Create a new table -table = Oasis::Etm::Table.new( - frame: 'all', - colsep: 1, - rowsep: 1, - tgroups: [ - Oasis::Etm::Tgroup.new( - cols: 3, - colspecs: [ - Oasis::Etm::Colspec.new(colnum: 1, colwidth: '1*'), - Oasis::Etm::Colspec.new(colnum: 2, colwidth: '2*'), - Oasis::Etm::Colspec.new(colnum: 3, colwidth: '1*') - ] - ) - ] -) - -# Convert to XML -xml = table.to_xml ----- - -=== XML Schema - -The OASIS ETM format follows this basic structure: - -[source,xml] ----- - - Sample Table - - - - - - - Header 1 - Header 2 - Header 3 - - - - - Cell 1 - Cell 2 - Cell 3 - - - -
----- - -== Contributing - -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. - -. Fork it -. Create your feature branch (`git checkout -b my-new-feature`) -. Commit your changes (`git commit -am 'Add some feature'`) -. Push to the branch (`git push origin my-new-feature`) -. Create new Pull Request - - -== License and Copyright - -This project is licensed under the BSD 2-clause License. -See the link:LICENSE.md[] file for details. - -Copyright Ribose. ---- END FILE: README.adoc --- ---- START FILE: Rakefile --- -# frozen_string_literal: true - -require "bundler/gem_tasks" -require "rspec/core/rake_task" - -RSpec::Core::RakeTask.new(:spec) - -require "rubocop/rake_task" - -RuboCop::RakeTask.new - -task default: %i[spec rubocop] ---- END FILE: Rakefile --- ---- START FILE: lib/oasis-etm.rb --- -require "oasis/etm" ---- END FILE: lib/oasis-etm.rb --- ---- START FILE: lib/oasis/etm.rb --- -# frozen_string_literal: true - -require "lutaml/model" -require_relative "etm/version" -require_relative "etm/table" - -module Oasis - module Etm - class Error < StandardError; end - - # Your code goes here... - end -end ---- END FILE: lib/oasis/etm.rb --- ---- START FILE: lib/oasis/etm/colspec.rb --- -module Oasis - module Etm - class Colspec < Lutaml::Model::Serializable - # Optional attributes - attribute :colnum, :integer - attribute :colname, :string - attribute :colwidth, :string - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :align, :string, values: %w[left right center justify char] - attribute :char, :string - attribute :charoff, :string - - xml do - root "colspec" - - map_attribute "colnum", to: :colnum - map_attribute "colname", to: :colname - map_attribute "colwidth", to: :colwidth - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "align", to: :align - map_attribute "char", to: :char - map_attribute "charoff", to: :charoff - end - end - end -end ---- END FILE: lib/oasis/etm/colspec.rb --- ---- START FILE: lib/oasis/etm/entry.rb --- -module Oasis - module Etm - class Entry < Lutaml::Model::Serializable - # Optional attributes - attribute :colname, :string - attribute :namest, :string - attribute :nameend, :string - attribute :morerows, :integer - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :align, :string, values: %w[left right center justify char] - attribute :char, :string - attribute :charoff, :string - attribute :valign, :string, values: %w[top middle bottom] - - # Content - attribute :content, :string - - xml do - root "entry" - - # Attribute mappings - map_attribute "colname", to: :colname - map_attribute "namest", to: :namest - map_attribute "nameend", to: :nameend - map_attribute "morerows", to: :morerows - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "align", to: :align - map_attribute "char", to: :char - map_attribute "charoff", to: :charoff - map_attribute "valign", to: :valign - - # Content mapping - map_content to: :content - end - end - end -end ---- END FILE: lib/oasis/etm/entry.rb --- ---- START FILE: lib/oasis/etm/row.rb --- -require_relative "entry" - -module Oasis - module Etm - class Row < Lutaml::Model::Serializable - # Optional attributes - attribute :rowsep, :integer, values: [0, 1] - attribute :valign, :string, values: %w[top middle bottom] - - # Content - attribute :entries, Entry, collection: true - - xml do - root "row" - - map_attribute "rowsep", to: :rowsep - map_attribute "valign", to: :valign - map_element "entry", to: :entries - end - end - end -end ---- END FILE: lib/oasis/etm/row.rb --- ---- START FILE: lib/oasis/etm/table.rb --- -require_relative "tgroup" - -module Oasis - module Etm - class Table < Lutaml::Model::Serializable - # Table attributes - attribute :frame, :string, values: %w[top bottom topbot all sides none] - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :pgwide, :integer, values: [0, 1] - - # Table content - attribute :title, :string - attribute :tgroups, Tgroup, collection: true - - xml do - root "table" - - # Frame mappings - map_attribute "frame", to: :frame - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "pgwide", to: :pgwide - - # Content mappings - map_element "title", to: :title - map_element "tgroup", to: :tgroups - end - end - end -end ---- END FILE: lib/oasis/etm/table.rb --- ---- START FILE: lib/oasis/etm/tbody.rb --- -require_relative "row" - -module Oasis - module Etm - class Tbody < Lutaml::Model::Serializable - # Optional attributes - attribute :valign, :string, values: %w[top middle bottom] - - # Content - attribute :rows, Row, collection: true - - xml do - root "tbody" - - map_attribute "valign", to: :valign - map_element "row", to: :rows - end - end - end -end ---- END FILE: lib/oasis/etm/tbody.rb --- ---- START FILE: lib/oasis/etm/tcol.rb --- -module Oasis - module Etm - class Colspec < Lutaml::Model::Serializable - # Optional attributes - attribute :colnum, :integer - attribute :colname, :string - attribute :colwidth, :string - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :align, :string, values: %w[left right center justify char] - attribute :char, :string - attribute :charoff, :string - - xml do - root "colspec" - - map_attribute "colnum", to: :colnum - map_attribute "colname", to: :colname - map_attribute "colwidth", to: :colwidth - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "align", to: :align - map_attribute "char", to: :char - map_attribute "charoff", to: :charoff - end - end - end -end ---- END FILE: lib/oasis/etm/tcol.rb --- ---- START FILE: lib/oasis/etm/tgroup.rb --- -require_relative "colspec" -require_relative "thead" -require_relative "tbody" - -module Oasis - module Etm - class Tgroup < Lutaml::Model::Serializable - # Required attributes - attribute :cols, :integer - - # Optional attributes - attribute :colsep, :integer, values: [0, 1] - attribute :rowsep, :integer, values: [0, 1] - attribute :align, :string, values: %w[left right center justify char] - - # Content - attribute :colspecs, Colspec, collection: true - attribute :thead, Thead - attribute :tbody, Tbody - - xml do - root "tgroup" - - # Attribute mappings - map_attribute "cols", to: :cols - map_attribute "colsep", to: :colsep - map_attribute "rowsep", to: :rowsep - map_attribute "align", to: :align - - # Content mappings - map_element "colspec", to: :colspecs - map_element "thead", to: :thead - map_element "tbody", to: :tbody - end - end - end -end ---- END FILE: lib/oasis/etm/tgroup.rb --- ---- START FILE: lib/oasis/etm/thead.rb --- -require_relative "row" - -module Oasis - module Etm - class Thead < Lutaml::Model::Serializable - # Optional attributes - attribute :valign, :string, values: %w[top middle bottom] - - # Content - attribute :rows, Row, collection: true - - xml do - root "thead" - - map_attribute "valign", to: :valign - map_element "row", to: :rows - end - end - end -end ---- END FILE: lib/oasis/etm/thead.rb --- ---- START FILE: lib/oasis/etm/version.rb --- -# frozen_string_literal: true - -module Oasis - module Etm - VERSION = "0.1.0" - end -end ---- END FILE: lib/oasis/etm/version.rb --- ---- START FILE: oasis-etm.gemspec --- -# frozen_string_literal: true - -require_relative "lib/oasis/etm/version" - -Gem::Specification.new do |spec| - spec.name = "oasis-etm" - spec.version = Oasis::Etm::VERSION - spec.authors = ["Ribose Inc."] - spec.email = ["open.source@ribose.com"] - - spec.summary = "Library for OASIS Exchange Table Model" - spec.description = <<~DESCRIPTION - Library for manipulation of OASIS Exchange Table Model XML. - DESCRIPTION - - spec.homepage = "https://github.com/lutaml/oasis-etm" - spec.license = "BSD-2-Clause" - - spec.bindir = "exe" - spec.require_paths = ["lib"] - spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0") - - # Specify which files should be added to the gem when it is released. - # The `git ls-files -z` loads the files in the - # RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path(__dir__)) do - `git ls-files -z`.split("\x0").reject do |f| - f.match(%r{^(test|features)/}) - end - end - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - - spec.add_dependency "lutaml-model" - spec.metadata["rubygems_mfa_required"] = "true" -end ---- END FILE: oasis-etm_wrapped.txt --- ---- START FILE: sig/oasis/etm.rbs --- -module Oasis - module Etm - VERSION: String - # See the writing guide of rbs: https://github.com/ruby/rbs#guides - end -end ---- END FILE: sig/oasis/etm.rbs --- ---- START FILE: spec/oasis/etm/colspec_spec.rb --- -RSpec.describe Oasis::Etm::Colspec do - let(:xml) do - <<~XML - - XML - end - - describe ".from_xml" do - subject(:colspec) { described_class.from_xml(xml) } - - it "parses all attributes" do - expect(colspec.colnum).to eq(1) - expect(colspec.colname).to eq("col1") - expect(colspec.colwidth).to eq("1*") - expect(colspec.colsep).to eq(1) - expect(colspec.rowsep).to eq(1) - expect(colspec.align).to eq("center") - expect(colspec.char).to eq(".") - expect(colspec.charoff).to eq("50") - end - end - - describe "#to_xml" do - subject(:colspec) do - described_class.new( - colnum: 1, - colname: "col1", - colwidth: "1*", - colsep: 1, - rowsep: 1, - align: "center", - char: ".", - charoff: "50", - ) - end - - it "generates valid XML" do - expect(colspec.to_xml).to be_analogous_with(xml) - end - end -end ---- END FILE: spec/oasis/etm/colspec_spec.rb --- ---- START FILE: spec/oasis/etm/entry_spec.rb --- -RSpec.describe Oasis::Etm::Entry do - let(:xml) do - <<~XML - Cell content - XML - end - - describe ".from_xml" do - subject(:entry) { described_class.from_xml(xml) } - - it "parses attributes" do - expect(entry.colname).to eq("col1") - expect(entry.namest).to eq("col1") - expect(entry.nameend).to eq("col2") - expect(entry.morerows).to eq(1) - expect(entry.colsep).to eq(1) - expect(entry.rowsep).to eq(1) - expect(entry.align).to eq("center") - expect(entry.char).to eq(".") - expect(entry.charoff).to eq("50") - expect(entry.valign).to eq("middle") - end - - it "parses content" do - expect(entry.content).to eq("Cell content") - end - end - - describe "#to_xml" do - subject(:entry) do - described_class.new( - colname: "col1", - namest: "col1", - nameend: "col2", - morerows: 1, - colsep: 1, - rowsep: 1, - align: "center", - char: ".", - charoff: "50", - valign: "middle", - content: "Cell content", - ) - end - - it "generates valid XML" do - expect(entry.to_xml).to be_analogous_with(xml) - end - end - - context "with validation" do - it "validates align values" do - expect { - described_class.new(align: "invalid") - }.to raise_error(Lutaml::Model::ValidationError) - end - - it "validates valign values" do - expect { - described_class.new(valign: "invalid") - }.to raise_error(Lutaml::Model::ValidationError) - end - - it "validates colsep values" do - expect { - described_class.new(colsep: 2) - }.to raise_error(Lutaml::Model::ValidationError) - end - - it "validates rowsep values" do - expect { - described_class.new(rowsep: 2) - }.to raise_error(Lutaml::Model::ValidationError) - end - end -end ---- END FILE: spec/oasis/etm/entry_spec.rb --- ---- START FILE: spec/oasis/etm/row_spec.rb --- -RSpec.describe Oasis::Etm::Row do - let(:xml) do - <<~XML - - Cell 1 - Cell 2 - Cell 3 - - XML - end - - describe ".from_xml" do - subject(:row) { described_class.from_xml(xml) } - - it "parses attributes" do - expect(row.rowsep).to eq(1) - expect(row.valign).to eq("middle") - end - - it "parses entries" do - expect(row.entries.size).to eq(3) - expect(row.entries.map(&:content)).to eq(["Cell 1", "Cell 2", "Cell 3"]) - end - end - - describe "#to_xml" do - subject(:row) do - described_class.new( - rowsep: 1, - valign: "middle", - entries: [ - Oasis::Etm::Entry.new(content: "Cell 1"), - Oasis::Etm::Entry.new(content: "Cell 2"), - Oasis::Etm::Entry.new(content: "Cell 3"), - ], - ) - end - - it "generates valid XML" do - expect(row.to_xml).to be_analogous_with(xml) - end - end -end ---- END FILE: spec/oasis/etm/row_spec.rb --- ---- START FILE: spec/oasis/etm/table_spec.rb --- -RSpec.describe Oasis::Etm::Table do - let(:xml) do - <<~XML - - Sample Table - - - - - - - Header 1 - Header 2 - Header 3 - - - - - Cell 1 - Cell 2 - Cell 3 - - - -
- XML - end - - describe ".from_xml" do - subject(:table) { described_class.from_xml(xml) } - - it "parses table attributes" do - expect(table.frame).to eq("all") - expect(table.colsep).to eq(1) - expect(table.rowsep).to eq(1) - end - - it "parses title" do - expect(table.title).to eq("Sample Table") - end - - it "parses tgroup" do - expect(table.tgroups.size).to eq(1) - expect(table.tgroups.first.cols).to eq(3) - end - end - - describe "#to_xml" do - subject(:table) do - described_class.new( - frame: "all", - colsep: 1, - rowsep: 1, - title: "Sample Table", - tgroups: [ - Oasis::Etm::Tgroup.new( - cols: 3, - colspecs: [ - Oasis::Etm::Colspec.new(colnum: 1, colwidth: "1*"), - Oasis::Etm::Colspec.new(colnum: 2, colwidth: "2*"), - Oasis::Etm::Colspec.new(colnum: 3, colwidth: "1*"), - ], - thead: Oasis::Etm::Thead.new( - rows: [ - Oasis::Etm::Row.new( - entries: [ - Oasis::Etm::Entry.new(content: "Header 1"), - Oasis::Etm::Entry.new(content: "Header 2"), - Oasis::Etm::Entry.new(content: "Header 3"), - ], - ), - ], - ), - tbody: Oasis::Etm::Tbody.new( - rows: [ - Oasis::Etm::Row.new( - entries: [ - Oasis::Etm::Entry.new(content: "Cell 1"), - Oasis::Etm::Entry.new(content: "Cell 2"), - Oasis::Etm::Entry.new(content: "Cell 3"), - ], - ), - ], - ), - ), - ], - ) - end - - it "generates valid XML" do - expect(table.to_xml).to be_analogous_with(xml) - end - end -end ---- END FILE: spec/oasis/etm/table_spec.rb --- ---- START FILE: spec/oasis/etm/tbody_spec.rb --- -RSpec.describe Oasis::Etm::Tbody do - let(:xml) do - <<~XML - - - Cell 1 - Cell 2 - Cell 3 - - - XML - end - - describe ".from_xml" do - subject(:tbody) { described_class.from_xml(xml) } - - it "parses valign attribute" do - expect(tbody.valign).to eq("top") - end - - it "parses rows" do - expect(tbody.rows.size).to eq(1) - expect(tbody.rows.first.entries.size).to eq(3) - expect(tbody.rows.first.entries.first.content).to eq("Cell 1") - end - end - - describe "#to_xml" do - subject(:tbody) do - described_class.new( - valign: "top", - rows: [ - Oasis::Etm::Row.new( - entries: [ - Oasis::Etm::Entry.new(content: "Cell 1"), - Oasis::Etm::Entry.new(content: "Cell 2"), - Oasis::Etm::Entry.new(content: "Cell 3"), - ], - ), - ], - ) - end - - it "generates valid XML" do - expect(tbody.to_xml).to be_analogous_with(xml) - end - end -end ---- END FILE: spec/oasis/etm/tbody_spec.rb --- ---- START FILE: spec/oasis/etm/tgroup_spec.rb --- -RSpec.describe Oasis::Etm::Tgroup do - let(:xml) do - <<~XML - - - - - - - Header 1 - Header 2 - Header 3 - - - - - Cell 1 - Cell 2 - Cell 3 - - - - XML - end - - describe ".from_xml" do - subject(:tgroup) { described_class.from_xml(xml) } - - it "parses required attributes" do - expect(tgroup.cols).to eq(3) - end - - it "parses optional attributes" do - expect(tgroup.colsep).to eq(1) - expect(tgroup.rowsep).to eq(1) - expect(tgroup.align).to eq("center") - end - - it "parses colspecs" do - expect(tgroup.colspecs.size).to eq(3) - expect(tgroup.colspecs.first.colnum).to eq(1) - expect(tgroup.colspecs.first.colwidth).to eq("1*") - end - - it "parses thead" do - expect(tgroup.thead).to be_a(Oasis::Etm::Thead) - expect(tgroup.thead.rows.size).to eq(1) - end - - it "parses tbody" do - expect(tgroup.tbody).to be_a(Oasis::Etm::Tbody) - expect(tgroup.tbody.rows.size).to eq(1) - end - end - - describe "#to_xml" do - subject(:tgroup) do - described_class.new( - cols: 3, - colsep: 1, - rowsep: 1, - align: "center", - colspecs: [ - Oasis::Etm::Colspec.new(colnum: 1, colwidth: "1*"), - Oasis::Etm::Colspec.new(colnum: 2, colwidth: "2*"), - Oasis::Etm::Colspec.new(colnum: 3, colwidth: "1*"), - ], - thead: Oasis::Etm::Thead.new( - rows: [ - Oasis::Etm::Row.new( - entries: [ - Oasis::Etm::Entry.new(content: "Header 1"), - Oasis::Etm::Entry.new(content: "Header 2"), - Oasis::Etm::Entry.new(content: "Header 3"), - ], - ), - ], - ), - tbody: Oasis::Etm::Tbody.new( - rows: [ - Oasis::Etm::Row.new( - entries: [ - Oasis::Etm::Entry.new(content: "Cell 1"), - Oasis::Etm::Entry.new(content: "Cell 2"), - Oasis::Etm::Entry.new(content: "Cell 3"), - ], - ), - ], - ), - ) - end - - it "generates valid XML" do - expect(tgroup.to_xml).to be_analogous_with(xml) - end - end -end ---- END FILE: spec/oasis/etm/tgroup_spec.rb --- ---- START FILE: spec/oasis/etm/thead_spec.rb --- -RSpec.describe Oasis::Etm::Thead do - let(:xml) do - <<~XML - - - Header 1 - Header 2 - Header 3 - - - XML - end - - describe ".from_xml" do - subject(:thead) { described_class.from_xml(xml) } - - it "parses valign attribute" do - expect(thead.valign).to eq("middle") - end - - it "parses rows" do - expect(thead.rows.size).to eq(1) - expect(thead.rows.first.entries.size).to eq(3) - expect(thead.rows.first.entries.first.content).to eq("Header 1") - end - end - - describe "#to_xml" do - subject(:thead) do - described_class.new( - valign: "middle", - rows: [ - Oasis::Etm::Row.new( - entries: [ - Oasis::Etm::Entry.new(content: "Header 1"), - Oasis::Etm::Entry.new(content: "Header 2"), - Oasis::Etm::Entry.new(content: "Header 3"), - ], - ), - ], - ) - end - - it "generates valid XML" do - expect(thead.to_xml).to be_analogous_with(xml) - end - end -end ---- END FILE: spec/oasis/etm/thead_spec.rb --- ---- START FILE: spec/oasis/etm_spec.rb --- -# frozen_string_literal: true - -RSpec.describe Oasis::Etm do - it "has a version number" do - expect(Oasis::Etm::VERSION).not_to be nil - end -end ---- END FILE: spec/oasis/etm_spec.rb --- ---- START FILE: spec/spec_helper.rb --- -# frozen_string_literal: true - -require "oasis-etm" -require "nokogiri" -require "xml-c14n" - -# Require all support files -Dir[File.join(__dir__, "support", "**", "*.rb")].sort.each { |f| require f } - -RSpec.configure do |config| - # Enable flags like --only-failures and --next-failure - config.example_status_persistence_file_path = ".rspec_status" - - # Disable RSpec exposing methods globally on `Module` and `main` - config.disable_monkey_patching! - - config.expect_with :rspec do |c| - c.syntax = :expect - end -end - -require "lutaml/model" -require "lutaml/model/xml_adapter/nokogiri_adapter" -require "lutaml/model/json_adapter/standard_json_adapter" -require "lutaml/model/yaml_adapter/standard_yaml_adapter" - -Lutaml::Model::Config.configure do |config| - config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter - config.json_adapter = Lutaml::Model::JsonAdapter::StandardJsonAdapter - config.yaml_adapter = Lutaml::Model::YamlAdapter::StandardYamlAdapter -end ---- END FILE: spec/spec_helper.rb --- ---- START FILE: spec/support/shared_examples/validation_examples.rb --- -# spec/support/shared_examples/validation_examples.rb -RSpec.shared_examples "validates attributes" do |attributes| - attributes.each do |attribute, valid_values| - context "with #{attribute}" do - it "accepts valid values" do - valid_values.each do |value| - expect { - described_class.new(attribute => value) - }.not_to raise_error - end - end - - it "rejects invalid values" do - expect { - described_class.new(attribute => "invalid") - }.to raise_error(Lutaml::Model::ValidationError) - end - end - end -end ---- END FILE: spec/support/shared_examples/validation_examples.rb --- diff --git a/spec/fixtures/native/docbook_example.xml b/spec/fixtures/native/docbook_example.xml index b0c1d77..d39369a 100644 --- a/spec/fixtures/native/docbook_example.xml +++ b/spec/fixtures/native/docbook_example.xml @@ -1,5 +1,6 @@ + Sample Table @@ -14,7 +15,7 @@ a5 - + b1