Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

124 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ruby library for NISO STS and ISOSTS

Purpose

The sts Ruby gem allows you to work with NISO STS and ISOSTS documents — two related XML formats for technical standards documents.

  • NISO STS (NISO Z39.96) — The standardized NISO format for journal and article publishing

  • ISOSTS — The internal precursor format to NISO STS, used by ISO before NISO standardization. ISOSTS adopts TBX (ISO 30042) for terminology markup.

Note
This is a work-in-progress.

Formats Compared

Aspect NISO STS ISOSTS

Standard

NISO Z39.96 (NISO standard)

Internal format (pre-NISO standardization)

History

Standardized version

Original internal format, predates NISO STS

Root element

<article>, <book>

<standard>

Metadata

article-meta, journal-meta

iso-meta, reg-meta, nat-meta

MathML version

3+ (via mml gem)

2 (custom Ruby implementation)

Math elements

mml:math + tex-math

mml:math only

Terminology

Inline TBX elements

term-sec with tbx:termEntry

Standards references

Mixed in ref-list

Dedicated std/std-ref elements

Module tree

Sts::NisoSts::*

Sts::IsoSts::*

Despite sharing the same JATS ancestry, the two formats have incompatible content models. Elements with the same XML name (e.g., p, sec, disp-formula) may have different permitted children and attributes. They are implemented as completely separate Ruby class trees.

Library

Usage: NISO STS

The following code parses a NISO STS XML document.

require 'sts'

doc = IO.read('spec/fixtures/tbx-nisosts-0.2.xml')
sts = Sts::NisoSts::Standard.from_xml(doc)
puts sts.to_xml(pretty: true)
# => NISO STS file round-tripped

NISO STS API

# Parse
sts = Sts::NisoSts::Standard.from_xml(xml_string)

# Access elements
sts.front.article_meta.title_wrap.main
sts.body.sec.first.label

# Serialize back
sts.to_xml
sts.to_xml(pretty: true)

# Check document type
sts.class.name # => "Sts::NisoSts::Standard"

NISO STS root classes

  • Sts::NisoSts::Standard — Book or article root

  • Sts::NisoSts::Front — Front matter (article-meta, journal-meta)

  • Sts::NisoSts::Body — Document body

  • Sts::NisoSts::Back — Back matter (references, footnotes)

Usage: ISOSTS

ISOSTS uses <standard> as the root element and includes MathML 2 for formulae. It adopts TBX (ISO 30042) for terminology sections.

require 'sts'

doc = IO.read('spec/fixtures/iso_sts/feature_doc.xml')
sts = Sts::IsoSts::Standard.from_xml(doc)
puts sts.to_xml(pretty: true)
# => ISOSTS file round-tripped

ISOSTS API

# Parse
sts = Sts::IsoSts::Standard.from_xml(xml_string)

# Access elements
sts.front.iso_meta.title_wrap.main
sts.front.iso_meta.std_ident.doc_number
sts.body.term_sec.first.term_entry.lang_set.first.term

# Serialize back
sts.to_xml
sts.to_xml(pretty: true)

# Check document type
sts.class.name # => "Sts::IsoSts::Standard"

ISOSTS root classes

  • Sts::IsoSts::Standard — Standard document root (<standard>)

  • Sts::IsoSts::Front — Front matter (iso-meta, reg-meta, nat-meta)

  • Sts::IsoSts::Body — Document body (includes term-sec for terminology)

  • Sts::IsoSts::Back — Back matter (annexes, references, footnotes)

ISOSTS MathML 2

ISOSTS uses MathML 2 (not MathML 3 like NISO STS). All MathML is provided by the mml gem, bound per host:

  • IsoSts::* math attributes → Mml::V2::Math

  • TbxIsoTml::* math attributes → Mml::V2::Math (TBX-in-ISOSTS only)

  • NisoSts::* math attributes → Mml::V3::Math

disp_formula = sts.body.sec.first.disp_formula
math = disp_formula.math  # => Mml::V2::Math

# Round-trip preserves mml: prefix
disp_formula.to_xml       # => <disp-formula><mml:math ...>...</mml:math></disp-formula>

MathML 2 and 3 share the same XML namespace (http://www.w3.org/1998/Math/MathML), so Mml::Namespace (the mml gem’s top-level namespace class) is used directly in both IsoSts::Standard#namespace_scope and NisoSts::Standard#namespace_scope.

ISOSTS TBX Terminology

ISOSTS uses TBX (TermBase eXchange, ISO 30042) for terminology sections via term-sec:

# Access terminology entries
term_sec = sts.body.term_sec.first
term_entry = term_sec.term_entry

term_entry.lang_set.each do |lang_set|
  puts lang_set.xml_lang        # => "en"
  puts lang_set.tig.first.term # => "medical device"
end

TBX elements reuse Sts::TbxIsoTml::* classes.

TBX Integration

Both NISO STS and ISOSTS support TBX (TermBase eXchange, ISO 30042) for terminology markup. The TBX elements are in the Sts::TbxIsoTml module:

require 'sts'

# NISO STS with TBX
sts = Sts::NisoSts::Standard.from_xml(xml_with_tbx)

# ISOSTS with TBX
sts = Sts::IsoSts::Standard.from_xml(xml_with_tbx)

Architecture principles

Namespace independence

IsoSts, NisoSts, and TbxIsoTml are independent schemas that genuinely diverge. Each Sts::<Namespace>::<Class> is modelled from its own schema source — never aliased across namespaces, never sharing base classes. The schemas disagree on most elements (e.g., IsoSts::Fig has title/alternatives that NisoSts::Figure lacks), so sharing types would fight the schemas and violate the Open/Closed principle.

Anti-pattern enforcement

spec/anti_patterns_spec.rb runs 9 per-file checks across lib/ to forbid: method_missing, respond_to_missing?, Object.const_get, .send(, instance_variable_set/get, respond_to? type-checks, hand-rolled serialization methods on Serializable subclasses (to_h, to_xml, from_xml, etc.), require_relative, and internal require. See CLAUDE.md for the rationale.

Schema validation

spec/schema_validation_spec.rb validates IsoSts output against the canonical reference-docs/isosts-v1/xsd/ISOSTS.xsd via Nokogiri::XML::Schema. Round-tripping alone cannot prove schema conformance (a model that invents or drops an attribute still round-trips symmetrically); the XSD is the only authoritative check.

Autoload convention

lib/sts.rb autoloads top-level namespaces. Each namespace’s lib/sts/<namespace>.rb autoloads every class in alphabetical order within category groups. External gems (lutaml/model, mml) are eager-required at the top of lib/sts.rb; internal code uses autoload only — no require_relative, no require "sts/…​".

Credits

This gem is developed, maintained and funded by Ribose Inc.

License

The gem is available as open source under the terms of the 2-Clause BSD License.

About

Ruby library for NISO STS and ISO STS

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages