diff --git a/TODO.sts-refactor/00-overview.md b/TODO.sts-refactor/00-overview.md
index 1cbe21b..3e82413 100644
--- a/TODO.sts-refactor/00-overview.md
+++ b/TODO.sts-refactor/00-overview.md
@@ -19,7 +19,7 @@
|---|------|----------|----------|--------------|
| 01 | `01-mathml-delegation.md` | Anti-Pattern Fix | DONE | — |
| 02 | `02-type-resolution.md` | Anti-Pattern Fix | DONE | — |
-| 03 | `03-namespace-coupling.md` | Architecture | IN PROGRESS | 01, 02 |
+| 03 | `03-namespace-coupling.md` | Architecture | IN PROGRESS (63→20 refs) | 01, 02 |
| 04 | `04-register-versioning.md` | Architecture | HIGH | 01, 02 |
| 05 | `05-missing-elements.md` | Feature Gap | MOSTLY DONE | 04 |
| 06 | `06-missing-attributes.md` | Feature Gap | DONE | 04 |
@@ -140,7 +140,9 @@ grep -r "method_missing|respond_to_missing|Object.const_get|\.send" lib/
```
### IsoSts Namespace Independence (2026-05-07)
-- ARCHITECTURE DECISION: IsoSts and NisoSts must remain fully independent
+- ARCHITECTURE DECISION: IsoSts must be independent **of NisoSts**. This is not
+ independence in general — `lib/sts/iso_sts/` still references `TbxIsoTml` and
+ MathML types directly, and those shared namespaces are outside this ADR.
- ISOSTS is frozen legacy; NISO STS evolves — combining them violates OCP
- Created 11 new IsoSts-specific types: Monospace, Sc, Strike, Underline, Uri,
NamedContent, StandardRef, MetaDate, ContentLanguage (with autoloads)
@@ -164,9 +166,27 @@ grep -r "method_missing|respond_to_missing|Object.const_get|\.send" lib/
- ~~Expand StringName usage (in contrib, element-citation, related-article — NISO STS 1.2)~~ → DONE: added to name-alternatives; already in person-group and mixed-citation
### Architectural Items (High Effort)
-- `03-namespace-coupling.md` — IN PROGRESS: 157→63 IsoSts→NisoSts cross-references remaining
+- `03-namespace-coupling.md` — IN PROGRESS: 63→20 IsoSts→NisoSts references
+ remaining (issue #40). Source of truth is `ISOSTS.xsd`, NOT the NisoSts
+ models — they disagree on nearly every element.
- `04-register-versioning.md` — Version the models via lutaml-model Registers
- `11-duplicate-models.md` — 44 overlapping element resolution (depends on 03)
+### Known bugs — schema conformance (separate from 03)
+The 2026-05-07 "@id added to all models (XSD-verified)" pass verified against
+the **NISO** XSD and applied the result to IsoSts. ISOSTS disagrees:
+- **16 IsoSts models silently drop ISOSTS attributes that exist** — real data
+ loss. `sub`/`sup` lose `arrange`+`specific-use`; `ext-link` loses 5 xlink
+ attrs; `mixed-citation` loses 6; `graphic`, `copyright-*`, `edition`,
+ `title`, `label`, `uri`, `named-content`, `underline`, `meta-date`, `body`
+ lose others.
+- **25 IsoSts models carry an `@id` ISOSTS does not define** — harmless (never
+ populated on parse, never emitted on serialise), but dead surface.
+
## Next Action
-Proceed with `03-namespace-coupling.md` — audit and resolve 157+ IsoSts→NisoSts cross-references.
+Two independent tracks:
+1. Finish `03` — the 20 remaining refs split into 11 deep-root refs (each
+ reaching a ~152-class recursive core) and 9 child-bearing refs whose closure
+ is unmeasured. Both need sizing before planning.
+2. File and fix the 16 lossy models above — real data loss, unrelated to
+ decoupling.
diff --git a/TODO.sts-refactor/03-namespace-coupling.md b/TODO.sts-refactor/03-namespace-coupling.md
index 6f347ac..06124ab 100644
--- a/TODO.sts-refactor/03-namespace-coupling.md
+++ b/TODO.sts-refactor/03-namespace-coupling.md
@@ -3,156 +3,117 @@
**Priority**: HIGH
**Category**: Architecture
**Estimated Effort**: High
-**Files Affected**: `lib/sts/iso_sts/content_groups/highlight_elements.rb` (194+ references)
+**Status**: Partially done — 63 → 20 references (GitHub issue #40)
## Problem
-`lib/sts/iso_sts/content_groups/highlight_elements.rb` contains 194+ references to `Sts::NisoSts::*` types:
-
-```ruby
-# Examples from highlight_elements.rb
-[:sub, "Sts::NisoSts::Sub", "sub"]
-[:sup, "Sts::NisoSts::Sup", "sup"]
-[:italic, "Sts::NisoSts::Italic", "italic"]
-[:bold, "Sts::NisoSts::Bold", "bold"]
-# ... 190 more
-```
-
-### Why This Is Wrong
-
-1. **Violation of namespace isolation**: IsoSts should not depend on NisoSts implementation
-2. **Shared-namespace ambiguity**: These elements appear in both ISOSTS and NISO STS but with different attribute sets
-3. **Tight coupling**: Changes to NisoSts can break IsoSts
-4. **Schema divergence ignored**: `
` in ISOSTS has different attributes than `
` in NISO STS Extended
-
-### Root Cause
-
-The schemas ARE different:
-- ISOSTS `
`: `@content-type, @id, @specific-use, @xml:lang`
-- NISO STS Extended `
`: `@content-type, @id, @originator, @specific-use, @style-type, @xml:base, @xml:lang`
-
-## Solution: Three-Tier Architecture
-
-### Tier 1: Shared Base Types
-
-Create shared types in `Sts::Base` that both namespaces inherit:
-
-```ruby
-# lib/sts/base/text/emphasis.rb
-module Sts
- module Base
- module Text
- class Emphasis < Lutaml::Model::Serializable
- # Shared attributes/methods
- attribute :id, :string
- attribute :base_fontsize, :string
- attribute :baseline_shift, :string
- attribute :color, :string
-
- xml do
- map_attribute :id, to: :id
- # ...
- end
- end
-
- class Bold < Emphasis
- xml { element "bold" }
- end
-
- class Italic < Emphasis
- xml { element "italic" }
- end
-
- class Sub < Emphasis
- xml { element "sub" }
- end
-
- class Sup < Emphasis
- xml { element "sup" }
- end
- end
- end
-end
-```
-
-### Tier 2: IsoSts-Specific Extensions
-
-```ruby
-# lib/sts/iso_sts/text/emphasis.rb
-module Sts
- module IsoSts
- module Text
- class Bold < ::Sts::Base::Text::Bold
- # Add IsoSts-specific attributes
- attribute :content_type, :string
-
- xml do
- # Override/add IsoSts-specific mapping
- map_attribute "content-type", to: :content_type
- end
- end
- end
- end
-end
-```
-
-### Tier 3: NisoSts-Specific Extensions
-
-```ruby
-# lib/sts/niso_sts/text/emphasis.rb
-module Sts
- module NisoSts
- module Text
- class Bold < ::Sts::Base::Text::Bold
- # Add NisoSts-specific attributes
- attribute :originator, :string
- attribute :style_type, :string
-
- xml do
- map_attribute "originator", to: :originator
- map_attribute "style-type", to: :style_type
- end
- end
- end
- end
-end
-```
-
-## Implementation Strategy
-
-1. **Phase 1**: Identify all shared element types (bold, italic, sub, sup, p, etc.)
-2. **Phase 2**: Create base types with MINIMAL shared attributes
-3. **Phase 3**: Refactor IsoSts to extend bases
-4. **Phase 4**: Refactor NisoSts to extend bases
-5. **Phase 5**: Delete `Sts::NisoSts::*` references from IsoSts content groups
-
-## Files to Refactor
-
-Primary targets:
-- `lib/sts/iso_sts/content_groups/highlight_elements.rb`
-- `lib/sts/iso_sts/content_groups/emphasis_elements.rb` (if exists)
-- `lib/sts/niso_sts/content_groups/highlight_elements.rb`
+`lib/sts/iso_sts/` references `Sts::NisoSts::*` types directly. IsoSts must be
+independent of NisoSts (ADR 2026-05-07): ISOSTS is frozen legacy, NISO STS
+evolves, so coupling them violates OCP.
+
+PR #31 reduced this from 157 to 63 references. Issue #40 reduced it further,
+from 63 to 20.
+
+## Source of truth: ISOSTS.xsd, NOT the NisoSts models
+
+The obvious approach — duplicate each NisoSts class into IsoSts — produces
+**schema-incorrect models**. The NisoSts models disagree with
+`reference-docs/isosts-v1/xsd/ISOSTS.xsd` on nearly every element:
+
+| Element | ISOSTS says | NisoSts model |
+|---|---|---|
+| `year` (:948) | `content-type`, `specific-use`, `xml:lang` — no `@id` | `@id` only |
+| `doc-type` (:6378) | `type="xs:string"` — no attributes at all | `@id` + content |
+| `ics` (:6373) | `type="xs:string"` | `@id` + `ics-desc` child |
+| `fpage` | `content-type`, `seq`, `specific-use`, `xml:lang`; no children | `@id` + bold/italic |
+| `license` (:51) | `license-type`, `specific-use`, `xml:lang` | `@id`, `xlink:href` |
+| `ruby` | **not an ISOSTS element** | exists (NISO only) |
+
+`feature_doc.xml` declares ``, and
+the ISOSTS DTD agrees with ISOSTS.xsd (both derive `bold`, `sub` etc. from the
+JATS 0.4 modules). ISOSTS.xsd is a faithful conversion and is the authority.
+
+**Round-tripping does not prove correctness.** A model that invents or drops an
+attribute still parses and serialises symmetrically, so the suite stays green
+while the model is wrong. Assert the exact attribute set per element instead.
+
+Attribute lists must be **generated** from the XSD, never hand-read: `version`
+on `tex-math` and `specific-use` on `pub-id` sit after long `xs:enumeration`
+blocks and are invisible to a truncated read.
+
+## Done in issue #40 — 43 refs removed, 27 classes added
+
+- **14 `xs:string` elements** (`originator`, `doc-type`, `doc-number`,
+ `part-number`, `version`, `suppl-type`, `suppl-number`, `suppl-version`,
+ `urn`, `sdo`, `proj-id`, `release-version`, `ics`, `secretariat`) — modelled
+ as content-only IsoSts classes with no attributes. 23 refs.
+- **3 `permissions` refs** repointed to the existing `IsoSts::Permissions`.
+- **`ruby` deleted** from `StyledContent` — ISOSTS defines no such element.
+ Behaviour change: `` in `` no longer round-trips.
+- **13 element classes** modelled from ISOSTS.xsd: `Year`, `PubDate`,
+ `ReleaseVersionId`, `IsProof`, `AltText`, `LongDesc`, `TexMath`, `PubId`,
+ `Volume`, `Issue`, `Fpage`, `Lpage`, `PageRange`. 16 refs.
+- **`WiNumber` added** — ISOSTS gives `wi-number` an `@id`; it was typed as a
+ plain string, silently discarding that `@id`.
+
+### Why classes and not plain `:string`
+
+`xs:string` elements look like they need no class. They do: an empty element
+(``, which `feature_doc.xml` contains) does not survive a `:string`
+round-trip. For a scalar, `render_empty: :empty` recovers it; for a collection
+(`secretariat`, `ics` — both `maxOccurs="unbounded"`) an empty element parses
+to `[]`, destroying the information at parse time before any render option
+applies. Content-only classes round-trip every case.
+
+## Remaining — 20 refs
+
+**11 refs to 9 deep roots**: `MetadataStd`, `ElementCitation`, `PersonGroup`,
+`Collab`, `Source`, `DispQuote`, `EditingInstruction`, `TermDisplay`,
+`BoxedText`. Each reaches the same ~152-class mutually-recursive core
+(`Section` → `Paragraph` → `DispQuote` → `Paragraph`). `DispQuote` has 3 direct
+children but pulls all 152. No incremental path — needs its own decision.
+
+**9 refs whose ISOSTS content models have real children**, closure not measured:
+`attrib` (:1082), `term-head` (:4308), `article-title`, `license` → `license-p`
+(:51), `publisher` → `publisher-loc`, `custom-meta-group` → `custom-meta`.
+`attrib` and `term-head` are **not** trivial leaves in ISOSTS despite what the
+NisoSts models suggest; `license-p` reaches `array`/`alternatives`, so these may
+not be cheap. Measure before planning.
+
+## Rejected: three-tier `Sts::Base` hierarchy
+
+An earlier draft of this document proposed shared base types in `Sts::Base` that
+both namespaces inherit. This contradicts the 2026-05-07 ADR, and the schemas
+genuinely diverge — `IsoSts::Fig` has `title`/`alternatives` that
+`NisoSts::Figure` lacks; `IsoSts::Ref` has `nlm-citation`/`citation-alternatives`
+that `NisoSts::Reference` lacks. A shared base would fight the schemas.
+
+That draft also targeted `lib/sts/iso_sts/content_groups/highlight_elements.rb`
+and "194+ references" to emphasis types. That file was deleted as dead code; the
+real work was metadata types, not highlight elements.
+
+## Naming trap (for the deferred work)
+
+A mechanical `s/NisoSts::/IsoSts::/` is wrong. Nine elements already have
+different class names per namespace, so a blind rename creates `IsoSts::Section`
+alongside the existing `IsoSts::Sec` — two classes for one `sec` element:
+
+`Section`/`Sec`, `Figure`/`Fig`, `Reference`/`Ref`, `ReferenceList`/`RefList`,
+`SectionArray`/`Array`, `StdCrossReference`/`StandardCrossReference`,
+`DisplayFormula`/`DispFormula`, `TermSection`/`TermSec`,
+`ReferenceStandard`/`Std`.
+
+Remap child references by **XML element name**, not class name.
+
+## Scope boundary
+
+Independence from NisoSts is not independence in general: `lib/sts/iso_sts/`
+still references 6 `TbxIsoTml` types directly, and much of the deferred closure
+reaches `TbxIsoTml`/MathML. Those are shared namespaces, outside this ADR.
## Verification
-1. No `Sts::NisoSts` references in `lib/sts/iso_sts/`
-2. All round-trip tests pass
-3. Schema validation against both ISOSTS DTD and NISO STS XSD passes
-
-## Dependencies
-
-- `01-mathml-delegation.md` — uses similar patterns
-- `02-type-resolution.md` — must be clean first
-
-## TODO Checklist
-
-- [ ] Audit all IsoSts → NisoSts references
-- [ ] Categorize by shared vs. truly namespace-specific
-- [ ] Design base type hierarchy
-- [ ] Create `lib/sts/base/` directory structure
-- [ ] Implement base types for shared elements
-- [ ] Refactor IsoSts to use base types
-- [ ] Refactor NisoSts to use base types
-- [ ] Remove cross-namespace references
-- [ ] Verify no circular dependencies
-- [ ] Run full test suite
+1. `grep -rho "Sts::NisoSts::" lib/sts/iso_sts/ | wc -l` → `20`
+2. Every attribute on an IsoSts model traces to a line in `ISOSTS.xsd`
+3. Autoload registry 1:1 with the directory (112/112)
+4. `bundle exec rspec` green; `bundle exec rubocop` clean
diff --git a/lib/sts/iso_sts.rb b/lib/sts/iso_sts.rb
index cc7eb63..20a4c4a 100644
--- a/lib/sts/iso_sts.rb
+++ b/lib/sts/iso_sts.rb
@@ -38,6 +38,33 @@ module IsoSts
autoload :MetaDate, "#{__dir__}/iso_sts/meta_date"
autoload :ContentLanguage, "#{__dir__}/iso_sts/content_language"
autoload :StandardRef, "#{__dir__}/iso_sts/standard_ref"
+ autoload :WiNumber, "#{__dir__}/iso_sts/wi_number"
+ autoload :Originator, "#{__dir__}/iso_sts/originator"
+ autoload :DocType, "#{__dir__}/iso_sts/doc_type"
+ autoload :DocNumber, "#{__dir__}/iso_sts/doc_number"
+ autoload :PartNumber, "#{__dir__}/iso_sts/part_number"
+ autoload :Version, "#{__dir__}/iso_sts/version"
+ autoload :SupplType, "#{__dir__}/iso_sts/suppl_type"
+ autoload :SupplNumber, "#{__dir__}/iso_sts/suppl_number"
+ autoload :SupplVersion, "#{__dir__}/iso_sts/suppl_version"
+ autoload :Urn, "#{__dir__}/iso_sts/urn"
+ autoload :Sdo, "#{__dir__}/iso_sts/sdo"
+ autoload :ProjId, "#{__dir__}/iso_sts/proj_id"
+ autoload :ReleaseVersion, "#{__dir__}/iso_sts/release_version"
+ autoload :Ics, "#{__dir__}/iso_sts/ics"
+ autoload :Year, "#{__dir__}/iso_sts/year"
+ autoload :PubDate, "#{__dir__}/iso_sts/pub_date"
+ autoload :ReleaseVersionId, "#{__dir__}/iso_sts/release_version_id"
+ autoload :IsProof, "#{__dir__}/iso_sts/is_proof"
+ autoload :AltText, "#{__dir__}/iso_sts/alt_text"
+ autoload :LongDesc, "#{__dir__}/iso_sts/long_desc"
+ autoload :TexMath, "#{__dir__}/iso_sts/tex_math"
+ autoload :PubId, "#{__dir__}/iso_sts/pub_id"
+ autoload :Volume, "#{__dir__}/iso_sts/volume"
+ autoload :Issue, "#{__dir__}/iso_sts/issue"
+ autoload :Fpage, "#{__dir__}/iso_sts/fpage"
+ autoload :Lpage, "#{__dir__}/iso_sts/lpage"
+ autoload :PageRange, "#{__dir__}/iso_sts/page_range"
# Section elements
autoload :Sec, "#{__dir__}/iso_sts/sec"
diff --git a/lib/sts/iso_sts/alt_text.rb b/lib/sts/iso_sts/alt_text.rb
new file mode 100644
index 0000000..6e0e339
--- /dev/null
+++ b/lib/sts/iso_sts/alt_text.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class AltText < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :id, :string
+ attribute :content_type, :string
+ attribute :specific_use, :string
+ attribute :xml_lang, :string
+
+ xml do
+ element "alt-text"
+
+ map_content to: :content
+ map_attribute "id", to: :id
+ map_attribute "content-type", to: :content_type
+ map_attribute "specific-use", to: :specific_use
+ map_attribute "xml:lang", to: :xml_lang
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/app.rb b/lib/sts/iso_sts/app.rb
index 5fc77d3..1d331b2 100644
--- a/lib/sts/iso_sts/app.rb
+++ b/lib/sts/iso_sts/app.rb
@@ -15,7 +15,7 @@ class App < Lutaml::Model::Serializable
attribute :term_sec, ::Sts::IsoSts::TermSec, collection: true
attribute :fn_group, ::Sts::IsoSts::FnGroup, collection: true
attribute :ref_list, ::Sts::IsoSts::RefList, collection: true
- attribute :permissions, ::Sts::NisoSts::Permissions
+ attribute :permissions, ::Sts::IsoSts::Permissions
attribute :non_normative_note, ::Sts::IsoSts::NonNormativeNote,
collection: true
attribute :non_normative_example, ::Sts::IsoSts::NonNormativeExample,
diff --git a/lib/sts/iso_sts/array.rb b/lib/sts/iso_sts/array.rb
index 9da2e28..2394ab4 100644
--- a/lib/sts/iso_sts/array.rb
+++ b/lib/sts/iso_sts/array.rb
@@ -12,7 +12,7 @@ class Array < Lutaml::Model::Serializable
attribute :label, ::Sts::IsoSts::Label
attribute :table, ::Sts::IsoSts::Table
attribute :attrib, ::Sts::NisoSts::Attrib, collection: true
- attribute :permissions, ::Sts::NisoSts::Permissions, collection: true
+ attribute :permissions, ::Sts::IsoSts::Permissions, collection: true
xml do
element "array"
diff --git a/lib/sts/iso_sts/disp_formula.rb b/lib/sts/iso_sts/disp_formula.rb
index 0f9dea8..6643b62 100644
--- a/lib/sts/iso_sts/disp_formula.rb
+++ b/lib/sts/iso_sts/disp_formula.rb
@@ -17,7 +17,7 @@ class DispFormula < Lutaml::Model::Serializable
attribute :styled_content, ::Sts::IsoSts::StyledContent
attribute :preformat, ::Sts::IsoSts::Preformat
attribute :graphic, ::Sts::IsoSts::Graphic, collection: true
- attribute :tex_math, ::Sts::NisoSts::TexMath
+ attribute :tex_math, ::Sts::IsoSts::TexMath
xml do
element "disp-formula"
diff --git a/lib/sts/iso_sts/doc_number.rb b/lib/sts/iso_sts/doc_number.rb
new file mode 100644
index 0000000..9237d6b
--- /dev/null
+++ b/lib/sts/iso_sts/doc_number.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class DocNumber < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "doc-number"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/doc_type.rb b/lib/sts/iso_sts/doc_type.rb
new file mode 100644
index 0000000..a729ab0
--- /dev/null
+++ b/lib/sts/iso_sts/doc_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class DocType < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "doc-type"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/document_identification.rb b/lib/sts/iso_sts/document_identification.rb
index 2e1f3df..b030b1c 100644
--- a/lib/sts/iso_sts/document_identification.rb
+++ b/lib/sts/iso_sts/document_identification.rb
@@ -4,11 +4,11 @@ module Sts
module IsoSts
class DocumentIdentification < Lutaml::Model::Serializable
attribute :id, :string
- attribute :sdo, ::Sts::NisoSts::Sdo
- attribute :proj_id, ::Sts::NisoSts::ProjId
+ attribute :sdo, ::Sts::IsoSts::Sdo
+ attribute :proj_id, ::Sts::IsoSts::ProjId
attribute :language, ::Sts::IsoSts::Language
- attribute :release_version, ::Sts::NisoSts::ReleaseVersion
- attribute :urn, ::Sts::NisoSts::Urn
+ attribute :release_version, ::Sts::IsoSts::ReleaseVersion
+ attribute :urn, ::Sts::IsoSts::Urn
xml do
element "doc-ident"
diff --git a/lib/sts/iso_sts/fpage.rb b/lib/sts/iso_sts/fpage.rb
new file mode 100644
index 0000000..de76153
--- /dev/null
+++ b/lib/sts/iso_sts/fpage.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class Fpage < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :content_type, :string
+ attribute :seq, :string
+ attribute :specific_use, :string
+ attribute :xml_lang, :string
+
+ xml do
+ element "fpage"
+
+ map_content to: :content
+ map_attribute "content-type", to: :content_type
+ map_attribute "seq", to: :seq
+ map_attribute "specific-use", to: :specific_use
+ map_attribute "xml:lang", to: :xml_lang
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/graphic.rb b/lib/sts/iso_sts/graphic.rb
index 142f464..bb24037 100644
--- a/lib/sts/iso_sts/graphic.rb
+++ b/lib/sts/iso_sts/graphic.rb
@@ -16,8 +16,8 @@ class Graphic < Lutaml::Model::Serializable
attribute :graphic_type, :string
attribute :label, ::Sts::IsoSts::Label
attribute :caption, ::Sts::IsoSts::Caption
- attribute :alt_text, ::Sts::NisoSts::AltText
- attribute :long_desc, ::Sts::NisoSts::LongDesc
+ attribute :alt_text, ::Sts::IsoSts::AltText
+ attribute :long_desc, ::Sts::IsoSts::LongDesc
xml do
element "graphic"
diff --git a/lib/sts/iso_sts/ics.rb b/lib/sts/iso_sts/ics.rb
new file mode 100644
index 0000000..acaa863
--- /dev/null
+++ b/lib/sts/iso_sts/ics.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class Ics < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "ics"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/is_proof.rb b/lib/sts/iso_sts/is_proof.rb
new file mode 100644
index 0000000..2835330
--- /dev/null
+++ b/lib/sts/iso_sts/is_proof.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as an empty complexType: its presence is the
+ # whole signal -- no attributes, no content.
+ class IsProof < Lutaml::Model::Serializable
+ xml do
+ element "is-proof"
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/iso_meta.rb b/lib/sts/iso_sts/iso_meta.rb
index 19e71e8..43dc1cd 100644
--- a/lib/sts/iso_sts/iso_meta.rb
+++ b/lib/sts/iso_sts/iso_meta.rb
@@ -14,7 +14,7 @@ class IsoMeta < Lutaml::Model::Serializable
attribute :release_date, ::Sts::IsoSts::ReleaseDate, collection: true
attribute :comm_ref, ::Sts::IsoSts::CommRef
attribute :secretariat, ::Sts::IsoSts::Secretariat, collection: true
- attribute :ics, ::Sts::NisoSts::Ics, collection: true
+ attribute :ics, ::Sts::IsoSts::Ics, collection: true
attribute :page_count, ::Sts::IsoSts::PageCount
attribute :permissions, ::Sts::IsoSts::Permissions, collection: true
attribute :std_xref, ::Sts::IsoSts::StandardCrossReference,
@@ -22,8 +22,8 @@ class IsoMeta < Lutaml::Model::Serializable
attribute :custom_meta_group, ::Sts::NisoSts::CustomMetaGroup,
collection: true
attribute :meta_date, ::Sts::IsoSts::MetaDate, collection: true
- attribute :pub_date, ::Sts::NisoSts::PubDate
- attribute :is_proof, ::Sts::NisoSts::IsProof
+ attribute :pub_date, ::Sts::IsoSts::PubDate
+ attribute :is_proof, ::Sts::IsoSts::IsProof
xml do
element "iso-meta"
diff --git a/lib/sts/iso_sts/issue.rb b/lib/sts/iso_sts/issue.rb
new file mode 100644
index 0000000..be0b74e
--- /dev/null
+++ b/lib/sts/iso_sts/issue.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class Issue < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :content_type, :string
+ attribute :seq, :string
+ attribute :specific_use, :string
+ attribute :xml_lang, :string
+
+ xml do
+ element "issue"
+
+ map_content to: :content
+ map_attribute "content-type", to: :content_type
+ map_attribute "seq", to: :seq
+ map_attribute "specific-use", to: :specific_use
+ map_attribute "xml:lang", to: :xml_lang
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/long_desc.rb b/lib/sts/iso_sts/long_desc.rb
new file mode 100644
index 0000000..a093b81
--- /dev/null
+++ b/lib/sts/iso_sts/long_desc.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class LongDesc < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :id, :string
+ attribute :content_type, :string
+ attribute :specific_use, :string
+ attribute :xml_lang, :string
+
+ xml do
+ element "long-desc"
+
+ map_content to: :content
+ map_attribute "id", to: :id
+ map_attribute "content-type", to: :content_type
+ map_attribute "specific-use", to: :specific_use
+ map_attribute "xml:lang", to: :xml_lang
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/lpage.rb b/lib/sts/iso_sts/lpage.rb
new file mode 100644
index 0000000..870f153
--- /dev/null
+++ b/lib/sts/iso_sts/lpage.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class Lpage < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :content_type, :string
+ attribute :specific_use, :string
+ attribute :xml_lang, :string
+
+ xml do
+ element "lpage"
+
+ map_content to: :content
+ map_attribute "content-type", to: :content_type
+ map_attribute "specific-use", to: :specific_use
+ map_attribute "xml:lang", to: :xml_lang
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/mixed_citation.rb b/lib/sts/iso_sts/mixed_citation.rb
index b6e12ab..74f67aa 100644
--- a/lib/sts/iso_sts/mixed_citation.rb
+++ b/lib/sts/iso_sts/mixed_citation.rb
@@ -24,16 +24,16 @@ class MixedCitation < Lutaml::Model::Serializable
attribute :break, ::Sts::IsoSts::Break, collection: true
attribute :person_group, ::Sts::NisoSts::PersonGroup, collection: true
attribute :collab, ::Sts::NisoSts::Collab, collection: true
- attribute :year, ::Sts::NisoSts::Year, collection: true
+ attribute :year, ::Sts::IsoSts::Year, collection: true
attribute :source, ::Sts::NisoSts::Source
attribute :article_title, ::Sts::NisoSts::ArticleTitle
- attribute :volume, ::Sts::NisoSts::Volume
- attribute :issue, ::Sts::NisoSts::Issue
- attribute :fpage, ::Sts::NisoSts::Fpage
- attribute :lpage, ::Sts::NisoSts::Lpage
- attribute :page_range, ::Sts::NisoSts::PageRange
+ attribute :volume, ::Sts::IsoSts::Volume
+ attribute :issue, ::Sts::IsoSts::Issue
+ attribute :fpage, ::Sts::IsoSts::Fpage
+ attribute :lpage, ::Sts::IsoSts::Lpage
+ attribute :page_range, ::Sts::IsoSts::PageRange
attribute :publisher, ::Sts::NisoSts::Publisher
- attribute :pub_id, ::Sts::NisoSts::PubId, collection: true
+ attribute :pub_id, ::Sts::IsoSts::PubId, collection: true
xml do
element "mixed-citation"
diff --git a/lib/sts/iso_sts/nat_meta.rb b/lib/sts/iso_sts/nat_meta.rb
index 2295d1b..cb362e7 100644
--- a/lib/sts/iso_sts/nat_meta.rb
+++ b/lib/sts/iso_sts/nat_meta.rb
@@ -14,8 +14,8 @@ class NatMeta < Lutaml::Model::Serializable
attribute :doc_ref, :string
attribute :release_date, ::Sts::IsoSts::ReleaseDate
attribute :comm_ref, :string
- attribute :secretariat, ::Sts::NisoSts::Secretariat, collection: true
- attribute :ics, ::Sts::NisoSts::Ics, collection: true
+ attribute :secretariat, ::Sts::IsoSts::Secretariat, collection: true
+ attribute :ics, ::Sts::IsoSts::Ics, collection: true
attribute :page_count, ::Sts::IsoSts::PageCount
attribute :permissions, ::Sts::IsoSts::Permissions, collection: true
attribute :std_xref, ::Sts::IsoSts::StandardCrossReference,
@@ -23,7 +23,7 @@ class NatMeta < Lutaml::Model::Serializable
attribute :custom_meta_group, ::Sts::NisoSts::CustomMetaGroup,
collection: true
attribute :meta_date, ::Sts::IsoSts::MetaDate, collection: true
- attribute :pub_date, ::Sts::NisoSts::PubDate
+ attribute :pub_date, ::Sts::IsoSts::PubDate
xml do
element "nat-meta"
diff --git a/lib/sts/iso_sts/originator.rb b/lib/sts/iso_sts/originator.rb
new file mode 100644
index 0000000..21d32c9
--- /dev/null
+++ b/lib/sts/iso_sts/originator.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class Originator < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "originator"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/page_range.rb b/lib/sts/iso_sts/page_range.rb
new file mode 100644
index 0000000..e02d62e
--- /dev/null
+++ b/lib/sts/iso_sts/page_range.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class PageRange < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :content_type, :string
+ attribute :specific_use, :string
+ attribute :xml_lang, :string
+
+ xml do
+ element "page-range"
+
+ map_content to: :content
+ map_attribute "content-type", to: :content_type
+ map_attribute "specific-use", to: :specific_use
+ map_attribute "xml:lang", to: :xml_lang
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/part_number.rb b/lib/sts/iso_sts/part_number.rb
new file mode 100644
index 0000000..d86ee78
--- /dev/null
+++ b/lib/sts/iso_sts/part_number.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class PartNumber < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "part-number"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/proj_id.rb b/lib/sts/iso_sts/proj_id.rb
new file mode 100644
index 0000000..a34ab85
--- /dev/null
+++ b/lib/sts/iso_sts/proj_id.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class ProjId < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "proj-id"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/pub_date.rb b/lib/sts/iso_sts/pub_date.rb
new file mode 100644
index 0000000..8a1c429
--- /dev/null
+++ b/lib/sts/iso_sts/pub_date.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class PubDate < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :pub_type, :string
+
+ xml do
+ element "pub-date"
+
+ map_content to: :content
+ map_attribute "pub-type", to: :pub_type
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/pub_id.rb b/lib/sts/iso_sts/pub_id.rb
new file mode 100644
index 0000000..e12f808
--- /dev/null
+++ b/lib/sts/iso_sts/pub_id.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class PubId < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :pub_id_type, :string
+ attribute :specific_use, :string
+
+ xml do
+ element "pub-id"
+
+ map_content to: :content
+ map_attribute "pub-id-type", to: :pub_id_type
+ map_attribute "specific-use", to: :specific_use
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/reg_meta.rb b/lib/sts/iso_sts/reg_meta.rb
index 6ed9935..caff0f7 100644
--- a/lib/sts/iso_sts/reg_meta.rb
+++ b/lib/sts/iso_sts/reg_meta.rb
@@ -14,8 +14,8 @@ class RegMeta < Lutaml::Model::Serializable
attribute :doc_ref, :string
attribute :release_date, ::Sts::IsoSts::ReleaseDate
attribute :comm_ref, :string
- attribute :secretariat, ::Sts::NisoSts::Secretariat, collection: true
- attribute :ics, ::Sts::NisoSts::Ics, collection: true
+ attribute :secretariat, ::Sts::IsoSts::Secretariat, collection: true
+ attribute :ics, ::Sts::IsoSts::Ics, collection: true
attribute :page_count, ::Sts::IsoSts::PageCount
attribute :permissions, ::Sts::IsoSts::Permissions, collection: true
attribute :std_xref, ::Sts::IsoSts::StandardCrossReference,
@@ -23,9 +23,9 @@ class RegMeta < Lutaml::Model::Serializable
attribute :custom_meta_group, ::Sts::NisoSts::CustomMetaGroup,
collection: true
attribute :meta_date, ::Sts::IsoSts::MetaDate, collection: true
- attribute :pub_date, ::Sts::NisoSts::PubDate
- attribute :wi_number, :string
- attribute :release_version_id, ::Sts::NisoSts::ReleaseVersionId
+ attribute :pub_date, ::Sts::IsoSts::PubDate
+ attribute :wi_number, ::Sts::IsoSts::WiNumber
+ attribute :release_version_id, ::Sts::IsoSts::ReleaseVersionId
xml do
element "reg-meta"
diff --git a/lib/sts/iso_sts/release_version.rb b/lib/sts/iso_sts/release_version.rb
new file mode 100644
index 0000000..ff06313
--- /dev/null
+++ b/lib/sts/iso_sts/release_version.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class ReleaseVersion < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "release-version"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/release_version_id.rb b/lib/sts/iso_sts/release_version_id.rb
new file mode 100644
index 0000000..debf9d4
--- /dev/null
+++ b/lib/sts/iso_sts/release_version_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class ReleaseVersionId < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :id, :string
+
+ xml do
+ element "release-version-id"
+
+ map_content to: :content
+ map_attribute "id", to: :id
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/sdo.rb b/lib/sts/iso_sts/sdo.rb
new file mode 100644
index 0000000..54285d3
--- /dev/null
+++ b/lib/sts/iso_sts/sdo.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class Sdo < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "sdo"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/secretariat.rb b/lib/sts/iso_sts/secretariat.rb
index debfb54..3dbd3a7 100644
--- a/lib/sts/iso_sts/secretariat.rb
+++ b/lib/sts/iso_sts/secretariat.rb
@@ -2,13 +2,12 @@
module Sts
module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
class Secretariat < Lutaml::Model::Serializable
- attribute :id, :string
- attribute :content, :string, collection: true
+ attribute :content, :string
+
xml do
element "secretariat"
- map_attribute "id", to: :id
- mixed_content
map_content to: :content
end
diff --git a/lib/sts/iso_sts/standard_identification.rb b/lib/sts/iso_sts/standard_identification.rb
index e3cfbff..6a301b4 100644
--- a/lib/sts/iso_sts/standard_identification.rb
+++ b/lib/sts/iso_sts/standard_identification.rb
@@ -4,15 +4,15 @@ module Sts
module IsoSts
class StandardIdentification < Lutaml::Model::Serializable
attribute :id, :string
- attribute :originator, ::Sts::NisoSts::Originator
- attribute :doc_type, ::Sts::NisoSts::DocType
- attribute :doc_number, ::Sts::NisoSts::DocNumber
- attribute :part_number, ::Sts::NisoSts::PartNumber
+ attribute :originator, ::Sts::IsoSts::Originator
+ attribute :doc_type, ::Sts::IsoSts::DocType
+ attribute :doc_number, ::Sts::IsoSts::DocNumber
+ attribute :part_number, ::Sts::IsoSts::PartNumber
attribute :edition, ::Sts::IsoSts::Edition
- attribute :version, ::Sts::NisoSts::Version
- attribute :suppl_type, ::Sts::NisoSts::SupplType
- attribute :suppl_number, ::Sts::NisoSts::SupplNumber
- attribute :suppl_version, ::Sts::NisoSts::SupplVersion
+ attribute :version, ::Sts::IsoSts::Version
+ attribute :suppl_type, ::Sts::IsoSts::SupplType
+ attribute :suppl_number, ::Sts::IsoSts::SupplNumber
+ attribute :suppl_version, ::Sts::IsoSts::SupplVersion
xml do
element "std-ident"
diff --git a/lib/sts/iso_sts/std_ref.rb b/lib/sts/iso_sts/std_ref.rb
index c0154ac..6feefdc 100644
--- a/lib/sts/iso_sts/std_ref.rb
+++ b/lib/sts/iso_sts/std_ref.rb
@@ -5,14 +5,14 @@ module IsoSts
class StdRef < Lutaml::Model::Serializable
attribute :id, :string
attribute :type, :string
- attribute :originator, ::Sts::NisoSts::Originator
- attribute :doc_type, ::Sts::NisoSts::DocType
- attribute :doc_number, ::Sts::NisoSts::DocNumber
- attribute :part_number, ::Sts::NisoSts::PartNumber
+ attribute :originator, ::Sts::IsoSts::Originator
+ attribute :doc_type, ::Sts::IsoSts::DocType
+ attribute :doc_number, ::Sts::IsoSts::DocNumber
+ attribute :part_number, ::Sts::IsoSts::PartNumber
attribute :edition, ::Sts::IsoSts::Edition
- attribute :suppl_type, ::Sts::NisoSts::SupplType
- attribute :suppl_number, ::Sts::NisoSts::SupplNumber
- attribute :year, ::Sts::NisoSts::Year
+ attribute :suppl_type, ::Sts::IsoSts::SupplType
+ attribute :suppl_number, ::Sts::IsoSts::SupplNumber
+ attribute :year, ::Sts::IsoSts::Year
attribute :content, :string, collection: true
xml do
element "std-ref"
diff --git a/lib/sts/iso_sts/styled_content.rb b/lib/sts/iso_sts/styled_content.rb
index 085afd2..61996ef 100644
--- a/lib/sts/iso_sts/styled_content.rb
+++ b/lib/sts/iso_sts/styled_content.rb
@@ -25,7 +25,6 @@ class StyledContent < Lutaml::Model::Serializable
attribute :sc, ::Sts::IsoSts::Sc, collection: true
attribute :strike, ::Sts::IsoSts::Strike, collection: true
attribute :underline, ::Sts::IsoSts::Underline, collection: true
- attribute :ruby, ::Sts::NisoSts::Ruby, collection: true
attribute :break, ::Sts::IsoSts::Break, collection: true
attribute :styled_content, ::Sts::IsoSts::StyledContent, collection: true
@@ -57,7 +56,6 @@ class StyledContent < Lutaml::Model::Serializable
map_element "sc", to: :sc
map_element "strike", to: :strike
map_element "underline", to: :underline
- map_element "ruby", to: :ruby
map_element "break", to: :break
map_element "styled-content", to: :styled_content
end
diff --git a/lib/sts/iso_sts/suppl_number.rb b/lib/sts/iso_sts/suppl_number.rb
new file mode 100644
index 0000000..98f156d
--- /dev/null
+++ b/lib/sts/iso_sts/suppl_number.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class SupplNumber < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "suppl-number"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/suppl_type.rb b/lib/sts/iso_sts/suppl_type.rb
new file mode 100644
index 0000000..0d83ea5
--- /dev/null
+++ b/lib/sts/iso_sts/suppl_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class SupplType < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "suppl-type"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/suppl_version.rb b/lib/sts/iso_sts/suppl_version.rb
new file mode 100644
index 0000000..997b837
--- /dev/null
+++ b/lib/sts/iso_sts/suppl_version.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class SupplVersion < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "suppl-version"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/table_wrap_foot.rb b/lib/sts/iso_sts/table_wrap_foot.rb
index 5be0991..2492fd5 100644
--- a/lib/sts/iso_sts/table_wrap_foot.rb
+++ b/lib/sts/iso_sts/table_wrap_foot.rb
@@ -11,7 +11,7 @@ class TableWrapFoot < Lutaml::Model::Serializable
attribute :fn_group, ::Sts::IsoSts::FnGroup
attribute :fn, ::Sts::IsoSts::Fn
attribute :attrib, ::Sts::NisoSts::Attrib
- attribute :permissions, ::Sts::NisoSts::Permissions
+ attribute :permissions, ::Sts::IsoSts::Permissions
xml do
element "table-wrap-foot"
diff --git a/lib/sts/iso_sts/tex_math.rb b/lib/sts/iso_sts/tex_math.rb
new file mode 100644
index 0000000..3c0ab9c
--- /dev/null
+++ b/lib/sts/iso_sts/tex_math.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class TexMath < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :id, :string
+ attribute :content_type, :string
+ attribute :notation, :string
+ attribute :version, :string
+
+ xml do
+ element "tex-math"
+
+ map_content to: :content
+ map_attribute "id", to: :id
+ map_attribute "content-type", to: :content_type
+ map_attribute "notation", to: :notation
+ map_attribute "version", to: :version
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/urn.rb b/lib/sts/iso_sts/urn.rb
new file mode 100644
index 0000000..09f2fcc
--- /dev/null
+++ b/lib/sts/iso_sts/urn.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class Urn < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "urn"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/version.rb b/lib/sts/iso_sts/version.rb
new file mode 100644
index 0000000..9c11fc7
--- /dev/null
+++ b/lib/sts/iso_sts/version.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as type="xs:string" -- no attributes.
+ class Version < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "version"
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/volume.rb b/lib/sts/iso_sts/volume.rb
new file mode 100644
index 0000000..47e5d6a
--- /dev/null
+++ b/lib/sts/iso_sts/volume.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class Volume < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :content_type, :string
+ attribute :seq, :string
+ attribute :specific_use, :string
+ attribute :xml_lang, :string
+
+ xml do
+ element "volume"
+
+ map_content to: :content
+ map_attribute "content-type", to: :content_type
+ map_attribute "seq", to: :seq
+ map_attribute "specific-use", to: :specific_use
+ map_attribute "xml:lang", to: :xml_lang
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/wi_number.rb b/lib/sts/iso_sts/wi_number.rb
new file mode 100644
index 0000000..01e8de9
--- /dev/null
+++ b/lib/sts/iso_sts/wi_number.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ # ISOSTS declares as mixed content carrying an @id. Modelling it
+ # as a plain string silently discarded that @id.
+ class WiNumber < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :id, :string
+
+ xml do
+ element "wi-number"
+
+ map_content to: :content
+ map_attribute "id", to: :id
+ end
+ end
+ end
+end
diff --git a/lib/sts/iso_sts/year.rb b/lib/sts/iso_sts/year.rb
new file mode 100644
index 0000000..736bb4d
--- /dev/null
+++ b/lib/sts/iso_sts/year.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Sts
+ module IsoSts
+ class Year < Lutaml::Model::Serializable
+ attribute :content, :string
+ attribute :content_type, :string
+ attribute :specific_use, :string
+ attribute :xml_lang, :string
+
+ xml do
+ element "year"
+
+ map_content to: :content
+ map_attribute "content-type", to: :content_type
+ map_attribute "specific-use", to: :specific_use
+ map_attribute "xml:lang", to: :xml_lang
+ end
+ end
+ end
+end
diff --git a/spec/iso_sts/iso_sts_element_spec.rb b/spec/iso_sts/iso_sts_element_spec.rb
index 0997ea1..4e8c4b2 100644
--- a/spec/iso_sts/iso_sts_element_spec.rb
+++ b/spec/iso_sts/iso_sts_element_spec.rb
@@ -427,4 +427,183 @@
expect(math).to be_a(Lutaml::Model::Serializable)
end
end
+
+ # ISOSTS declares these elements as type="xs:string": text content, no
+ # attributes. They are modelled as IsoSts classes rather than plain strings
+ # because an empty element () does not survive a :string round-trip --
+ # for a collection it parses to [], losing the element entirely.
+ describe "ISOSTS xs:string elements" do
+ {
+ Originator: "originator",
+ DocType: "doc-type",
+ DocNumber: "doc-number",
+ PartNumber: "part-number",
+ Version: "version",
+ SupplType: "suppl-type",
+ SupplNumber: "suppl-number",
+ SupplVersion: "suppl-version",
+ Urn: "urn",
+ Sdo: "sdo",
+ ProjId: "proj-id",
+ ReleaseVersion: "release-version",
+ Ics: "ics",
+ Secretariat: "secretariat",
+ }.each do |klass, element|
+ it "IsoSts::#{klass} maps <#{element}>" do
+ model = described_class.const_get(klass)
+ expect(model.mappings_for(:xml).root_element).to eq(element)
+ end
+
+ it "IsoSts::#{klass} has only content, as ISOSTS defines no attributes" do
+ model = described_class.const_get(klass)
+ expect(model.attributes.keys).to eq(%i[content])
+ end
+
+ it "IsoSts::#{klass} round-trips an empty <#{element}/>" do
+ model = described_class.const_get(klass)
+ xml = "<#{element}/>"
+ expect(model.to_xml(model.from_xml(xml)).strip).to eq(xml)
+ end
+ end
+ end
+
+ describe "IsoSts models that reference the xs:string element classes" do
+ {
+ "StandardIdentification" => {
+ originator: :Originator, doc_type: :DocType, doc_number: :DocNumber,
+ part_number: :PartNumber, version: :Version, suppl_type: :SupplType,
+ suppl_number: :SupplNumber, suppl_version: :SupplVersion
+ },
+ "StdRef" => {
+ originator: :Originator, doc_type: :DocType, doc_number: :DocNumber,
+ part_number: :PartNumber, suppl_type: :SupplType,
+ suppl_number: :SupplNumber
+ },
+ "DocumentIdentification" => {
+ sdo: :Sdo, proj_id: :ProjId, release_version: :ReleaseVersion,
+ urn: :Urn
+ },
+ "RegMeta" => { secretariat: :Secretariat, ics: :Ics },
+ "NatMeta" => { secretariat: :Secretariat, ics: :Ics },
+ "IsoMeta" => { secretariat: :Secretariat, ics: :Ics },
+ }.each do |model_name, expectations|
+ expectations.each do |attr, klass|
+ it "#{model_name}##{attr} uses IsoSts::#{klass}" do
+ model = described_class.const_get(model_name)
+ expect(model.attributes[attr].type)
+ .to eq(described_class.const_get(klass))
+ end
+ end
+ end
+ end
+
+ # Attribute sets below are transcribed from ISOSTS.xsd. Round-tripping does
+ # not prove them: a model that invents or drops an attribute still parses and
+ # serialises symmetrically. Asserting the exact set is what catches that.
+ describe "ISOSTS-modelled element classes" do
+ {
+ Year: %i[content content_type specific_use xml_lang],
+ PubDate: %i[content pub_type],
+ ReleaseVersionId: %i[content id],
+ AltText: %i[content id content_type specific_use xml_lang],
+ LongDesc: %i[content id content_type specific_use xml_lang],
+ TexMath: %i[content id content_type notation version],
+ PubId: %i[content pub_id_type specific_use],
+ Volume: %i[content content_type seq specific_use xml_lang],
+ Issue: %i[content content_type seq specific_use xml_lang],
+ Fpage: %i[content content_type seq specific_use xml_lang],
+ Lpage: %i[content content_type specific_use xml_lang],
+ PageRange: %i[content content_type specific_use xml_lang],
+ }.each do |klass, expected|
+ it "IsoSts::#{klass} models exactly the ISOSTS attribute set" do
+ expect(described_class.const_get(klass).attributes.keys)
+ .to match_array(expected)
+ end
+ end
+
+ it "IsoSts::Year has no id, which ISOSTS does not define" do
+ expect(described_class::Year.attributes).not_to have_key(:id)
+ end
+
+ it "IsoSts::Fpage carries seq but IsoSts::Lpage does not" do
+ expect(described_class::Fpage.attributes).to have_key(:seq)
+ expect(described_class::Lpage.attributes).not_to have_key(:seq)
+ end
+
+ it "IsoSts::Fpage models no bold or italic children" do
+ expect(described_class::Fpage.attributes).not_to have_key(:bold)
+ expect(described_class::Fpage.attributes).not_to have_key(:italic)
+ end
+
+ it "IsoSts::IsProof is an empty element" do
+ expect(described_class::IsProof.attributes).to be_empty
+ round_tripped = described_class::IsProof
+ .to_xml(described_class::IsProof.new).strip
+ expect(round_tripped).to eq("")
+ end
+ end
+
+ describe "IsoSts models that reference the ISOSTS-modelled classes" do
+ {
+ "StdRef" => { year: :Year },
+ "MixedCitation" => {
+ year: :Year, volume: :Volume, issue: :Issue, fpage: :Fpage,
+ lpage: :Lpage, page_range: :PageRange, pub_id: :PubId
+ },
+ "RegMeta" => {
+ pub_date: :PubDate, release_version_id: :ReleaseVersionId
+ },
+ "IsoMeta" => { pub_date: :PubDate, is_proof: :IsProof },
+ "NatMeta" => { pub_date: :PubDate },
+ "Graphic" => { alt_text: :AltText, long_desc: :LongDesc },
+ "DispFormula" => { tex_math: :TexMath },
+ }.each do |model_name, expectations|
+ expectations.each do |attr, klass|
+ it "#{model_name}##{attr} uses IsoSts::#{klass}" do
+ model = described_class.const_get(model_name)
+ expect(model.attributes[attr].type)
+ .to eq(described_class.const_get(klass))
+ end
+ end
+ end
+ end
+
+ # ISOSTS is copyright-statement*, copyright-year*,
+ # copyright-holder*, license* -- exactly what IsoSts::Permissions models.
+ describe "permissions uses the IsoSts model" do
+ %w[Array App TableWrapFoot].each do |model_name|
+ it "#{model_name}#permissions is IsoSts::Permissions" do
+ model = described_class.const_get(model_name)
+ expect(model.attributes[:permissions].type)
+ .to eq(described_class::Permissions)
+ end
+ end
+ end
+
+ # ISOSTS defines no element; only NISO STS does.
+ describe "styled-content matches the ISOSTS content model" do
+ it "does not model , which ISOSTS does not define" do
+ expect(described_class::StyledContent.attributes).not_to have_key(:ruby)
+ end
+ end
+
+ # ISOSTS gives an @id; modelling it as a plain string dropped it.
+ describe "IsoSts::WiNumber" do
+ it "models the @id that ISOSTS defines" do
+ expect(described_class::WiNumber.attributes.keys)
+ .to match_array(%i[content id])
+ end
+
+ it "preserves @id through a round-trip" do
+ xml = '12345'
+ parsed = described_class::WiNumber.from_xml(xml)
+ expect(parsed.id).to eq("wi-1")
+ expect(described_class::WiNumber.to_xml(parsed).strip).to eq(xml)
+ end
+
+ it "is used by RegMeta rather than a plain string" do
+ expect(described_class::RegMeta.attributes[:wi_number].type)
+ .to eq(described_class::WiNumber)
+ end
+ end
end