sts 0.6.6 → 0.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/TODO.roadmap/00-overview.md +85 -0
- data/TODO.roadmap/01-mathml-namespace-deduplication.md +62 -0
- data/TODO.roadmap/02-lutaml-model-element-builder-dispatch.md +115 -0
- data/TODO.roadmap/03-issue-40-child-bearing-roots.md +57 -0
- data/TODO.roadmap/04-issue-40-recursive-roots.md +105 -0
- data/TODO.roadmap/05-content-mathml-unification.md +75 -0
- data/TODO.roadmap/07-tbxisotml-misclassification-audit.md +82 -0
- data/TODO.roadmap/08-register-versioning.md +95 -0
- data/TODO.roadmap/09-test-coverage-gaps.md +78 -0
- data/TODO.roadmap/10-iso-sts-common-attributes-module.md +115 -0
- data/TODO.roadmap/11-docs-and-readme-refresh.md +52 -0
- data/TODO.sts-refactor/00-overview.md +3 -3
- data/TODO.sts-refactor/03-namespace-coupling.md +13 -5
- data/lib/sts/iso_sts/custom_meta.rb +37 -0
- data/lib/sts/iso_sts/custom_meta_group.rb +16 -0
- data/lib/sts/iso_sts/def_list.rb +1 -1
- data/lib/sts/iso_sts/iso_meta.rb +1 -1
- data/lib/sts/iso_sts/license.rb +35 -0
- data/lib/sts/iso_sts/license_p.rb +96 -0
- data/lib/sts/iso_sts/meta_name.rb +14 -0
- data/lib/sts/iso_sts/meta_value.rb +41 -0
- data/lib/sts/iso_sts/nat_meta.rb +1 -1
- data/lib/sts/iso_sts/permissions.rb +1 -1
- data/lib/sts/iso_sts/reg_meta.rb +1 -1
- data/lib/sts/iso_sts/standard.rb +1 -1
- data/lib/sts/iso_sts/term_head.rb +74 -0
- data/lib/sts/iso_sts.rb +7 -0
- data/lib/sts/namespaces.rb +0 -5
- data/lib/sts/niso_sts/mml_content.rb +1 -1
- data/lib/sts/niso_sts/standard.rb +1 -1
- data/lib/sts/version.rb +1 -1
- metadata +20 -2
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# C.08: Register versioning for STS schema versions
|
|
2
|
+
|
|
3
|
+
**Status**: planning. Significant API design.
|
|
4
|
+
**Original doc**: `TODO.sts-refactor/04-register-versioning.md` (HIGH
|
|
5
|
+
priority, untouched).
|
|
6
|
+
**Estimated effort**: large (multi-week).
|
|
7
|
+
|
|
8
|
+
## Problem
|
|
9
|
+
|
|
10
|
+
sts-ruby today ships a single `Sts::IsoSts` and `Sts::NisoSts` namespace.
|
|
11
|
+
Each maps to one schema version (ISOSTS v1.1, NISO STS 1.0). Real-world
|
|
12
|
+
documents use multiple versions:
|
|
13
|
+
|
|
14
|
+
- ISOSTS v1.1 (2013, frozen)
|
|
15
|
+
- NISO STS 1.0 (2017)
|
|
16
|
+
- NISO STS 1.2 (2022, evolving)
|
|
17
|
+
|
|
18
|
+
When a 1.2-specific element (`<processing-meta>`, `<code>`, `<legend>`) is
|
|
19
|
+
modelled, it lives in `Sts::NisoSts::*` alongside 1.0 elements. There's no
|
|
20
|
+
way to parse a document as "NISO STS 1.0 only" and reject 1.2 elements.
|
|
21
|
+
|
|
22
|
+
## Goal
|
|
23
|
+
|
|
24
|
+
Use lutaml-model's `Register` system to version the model classes. The
|
|
25
|
+
mml gem already does this:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
module Mml
|
|
29
|
+
module V2
|
|
30
|
+
class Math < CommonElements
|
|
31
|
+
def self.lutaml_default_register
|
|
32
|
+
:mml_v2
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Each MathML version is a separate module with its own context. sts-ruby
|
|
40
|
+
should follow the same pattern: `Sts::IsoSts::V1_1::*`, `Sts::NisoSts::V1_0::*`,
|
|
41
|
+
`Sts::NisoSts::V1_2::*`.
|
|
42
|
+
|
|
43
|
+
## Plan (high level)
|
|
44
|
+
|
|
45
|
+
1. **API design** — decide caller-facing entrypoint:
|
|
46
|
+
- Option A: `Sts.parse(xml, version: :nisosts_1_0)` — explicit
|
|
47
|
+
- Option B: auto-detect from DOCTYPE / `dtd-version` attribute
|
|
48
|
+
- Option C: keep `Sts::NisoSts::*` as the latest alias, add
|
|
49
|
+
`Sts::NisoSts::V1_0::*` etc. for version-specific access
|
|
50
|
+
2. **Re-namespace** — move every existing `Sts::NisoSts::*` class to
|
|
51
|
+
`Sts::NisoSts::V1_2::*` (or wherever it belongs based on schema
|
|
52
|
+
history). Keep backward-compat aliases.
|
|
53
|
+
3. **Cross-version testing** — same fixture parsed under different
|
|
54
|
+
versions should accept/reject the right elements.
|
|
55
|
+
4. **Version-specific elements** — `<processing-meta>` (1.2-only) lives
|
|
56
|
+
only in V1_2; parsing it under V1_0 raises (or warns).
|
|
57
|
+
|
|
58
|
+
## Risks
|
|
59
|
+
|
|
60
|
+
- **Breaking API change** — current callers use `Sts::NisoSts::Standard`
|
|
61
|
+
without a version. Any re-namespace breaks them.
|
|
62
|
+
- **Cross-version references** — if V1_2::Standard contains V1_0::Paragraph
|
|
63
|
+
(because Paragraph hasn't changed), the type references cross versions.
|
|
64
|
+
Needs careful design.
|
|
65
|
+
- **Migration burden** — large existing model surface.
|
|
66
|
+
|
|
67
|
+
## Decision needed
|
|
68
|
+
|
|
69
|
+
This is the largest remaining architectural work. Before starting:
|
|
70
|
+
|
|
71
|
+
1. Confirm the use case (do downstream consumers actually need version
|
|
72
|
+
discrimination?)
|
|
73
|
+
2. Decide the API (Options A/B/C above)
|
|
74
|
+
3. Plan migration path for existing callers
|
|
75
|
+
|
|
76
|
+
## Files affected
|
|
77
|
+
|
|
78
|
+
- Every `lib/sts/niso_sts/*.rb` (~200 classes)
|
|
79
|
+
- Every `lib/sts/iso_sts/*.rb` (~150 classes)
|
|
80
|
+
- All specs that reference classes by current names
|
|
81
|
+
|
|
82
|
+
## How to apply
|
|
83
|
+
|
|
84
|
+
- Don't start until the design is approved
|
|
85
|
+
- Read mml gem's `lib/mml/versioned_parser.rb` and
|
|
86
|
+
`lib/mml/context_configuration.rb` for the established pattern
|
|
87
|
+
- Consider a small proof-of-concept (version one element family — e.g.,
|
|
88
|
+
`<list>` — across versions) before committing
|
|
89
|
+
|
|
90
|
+
## Verification
|
|
91
|
+
|
|
92
|
+
- Each version's classes round-trip its corresponding schema's fixtures
|
|
93
|
+
- Cross-version parsing is explicitly tested
|
|
94
|
+
- Existing callers can opt in incrementally (backward compat for at least
|
|
95
|
+
one release)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# D.09: Test coverage gaps
|
|
2
|
+
|
|
3
|
+
**Status**: ongoing. Original doc: `TODO.sts-refactor/10-test-coverage.md`.
|
|
4
|
+
**Estimated effort**: medium, distributed across future PRs.
|
|
5
|
+
|
|
6
|
+
## Current state
|
|
7
|
+
|
|
8
|
+
- **2563 examples, 0 failures**
|
|
9
|
+
- Anti-pattern enforcement: 9 per-file checks in `spec/anti_patterns_spec.rb`
|
|
10
|
+
- Per-model attribute-set assertions: ~50 models covered (mostly IsoSts
|
|
11
|
+
recent additions)
|
|
12
|
+
- Round-trip coverage: `spec/round_trip/reference_docs_spec.rb` exercises
|
|
13
|
+
real fixtures
|
|
14
|
+
- Coverage: 99.8% line coverage (per TODO.sts-refactor/10)
|
|
15
|
+
|
|
16
|
+
## Gaps
|
|
17
|
+
|
|
18
|
+
### 1. Schema-validation tests
|
|
19
|
+
|
|
20
|
+
Currently absent. Each model is asserted against an attribute set in
|
|
21
|
+
specs, but no test validates model output against the actual XSDs in
|
|
22
|
+
`reference-docs/`. A schema-validation spec would catch:
|
|
23
|
+
|
|
24
|
+
- Attributes the model invents (not in XSD)
|
|
25
|
+
- Required attributes the model drops
|
|
26
|
+
- Element nesting the XSD forbids
|
|
27
|
+
|
|
28
|
+
Implementation: `Nokogiri::XML::Schema` to validate serialized output
|
|
29
|
+
against `reference-docs/isosts-v1/xsd/ISOSTS.xsd` and
|
|
30
|
+
`reference-docs/NISO-STS-extended-1-MathML3-XSD/`.
|
|
31
|
+
|
|
32
|
+
### 2. Performance tests
|
|
33
|
+
|
|
34
|
+
Currently absent. The user's TODO.sts-refactor/10 lists these as
|
|
35
|
+
"needed". sts-ruby parses real ISO documents (some 1MB+); parsing time
|
|
36
|
+
and memory pressure should be tracked.
|
|
37
|
+
|
|
38
|
+
Implementation: `rspec-benchmark` or similar. Bench against the largest
|
|
39
|
+
fixture (`spec/fixtures/mn-samples-iso-private/`). Track regressions
|
|
40
|
+
across releases.
|
|
41
|
+
|
|
42
|
+
### 3. Concurrent-parse tests
|
|
43
|
+
|
|
44
|
+
`Lutaml::Model::TransformationRegistry` uses mutexes for thread safety
|
|
45
|
+
(lib/lutaml/model/transformation_registry.rb:92-101). No spec covers
|
|
46
|
+
concurrent parsing. Worth a thread-spawning test that hammers the
|
|
47
|
+
registry from multiple threads to catch any race.
|
|
48
|
+
|
|
49
|
+
### 4. Versioning tests (blocked on C.08)
|
|
50
|
+
|
|
51
|
+
Once Register versioning exists, add specs that the same document parses
|
|
52
|
+
differently under different versions, and that version-incompatible
|
|
53
|
+
elements are rejected.
|
|
54
|
+
|
|
55
|
+
### 5. Cross-namespace round-trip
|
|
56
|
+
|
|
57
|
+
`spec/iso_sts/iso_sts_element_spec.rb` and `spec/sts_spec.rb` cover
|
|
58
|
+
IsoSts and NisoSts separately. No spec exercises a TBX-in-ISOSTS document
|
|
59
|
+
end-to-end (TBX elements inside IsoSts Standard with MathML 2 content).
|
|
60
|
+
A round-trip test for `spec/fixtures/tbx-nisosts-0.2.xml`-style documents
|
|
61
|
+
across all three namespaces would catch integration regressions.
|
|
62
|
+
|
|
63
|
+
### 6. Profile validation (existing)
|
|
64
|
+
|
|
65
|
+
`spec/profiles/iso_iec_validator_spec.rb` — 11 specs. Covers structural,
|
|
66
|
+
metadata, originator, doc-type validation. Looks healthy.
|
|
67
|
+
|
|
68
|
+
## How to apply
|
|
69
|
+
|
|
70
|
+
- Add schema-validation spec first (highest value, mechanical to write)
|
|
71
|
+
- Add performance spec next (gives a baseline before C.05/C.08 land)
|
|
72
|
+
- Concurrent-parse spec is small and high-value — fit it in alongside any
|
|
73
|
+
future lutaml-model bump
|
|
74
|
+
- Versioning and cross-namespace specs block on C.08
|
|
75
|
+
|
|
76
|
+
## Verification
|
|
77
|
+
|
|
78
|
+
Each new spec file passes locally and on CI. Coverage stays at ≥99.5%.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# D.10: IsoSts common-attribute module (DRY within namespace)
|
|
2
|
+
|
|
3
|
+
**Status**: proposal. Needs approval before implementing.
|
|
4
|
+
**Estimated effort**: medium (touches ~50 classes).
|
|
5
|
+
|
|
6
|
+
## Problem
|
|
7
|
+
|
|
8
|
+
Many IsoSts classes share the same attribute set:
|
|
9
|
+
|
|
10
|
+
| Pattern | Attributes | Used by |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| Date parts | `id content_type specific_use xml_lang` | Day, Month, Season, Etal (partial) |
|
|
13
|
+
| Contact (simple) | `id content_type specific_use content` | Phone, Fax |
|
|
14
|
+
| xlink extension | `xlink_type xlink_href xlink_role xlink_title xlink_show xlink_actuate` | Abbrev, Email, ExtLink, Institution, InlineGraphic, MixedCitation |
|
|
15
|
+
| Citation-common | `id content_type specific_use xml_lang originator` | (various) |
|
|
16
|
+
|
|
17
|
+
This is fine-grained duplication. Each class is ~20-30 lines, mostly
|
|
18
|
+
attribute declarations. A single attribute rename across the schema (e.g.,
|
|
19
|
+
`xml:lang` semantics change) requires updating 30+ files.
|
|
20
|
+
|
|
21
|
+
## Proposal
|
|
22
|
+
|
|
23
|
+
Within the IsoSts namespace only (NOT cross-namespace — that's forbidden
|
|
24
|
+
by the ADR), define modules:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
module Sts
|
|
28
|
+
module IsoSts
|
|
29
|
+
module CommonAttributes
|
|
30
|
+
# XLink attributes — included into classes that wrap XLink-extending elements
|
|
31
|
+
module Xlink
|
|
32
|
+
def self.included(base)
|
|
33
|
+
base.class_eval do
|
|
34
|
+
attribute :xlink_type, :string
|
|
35
|
+
attribute :xlink_href, :string
|
|
36
|
+
attribute :xlink_role, :string
|
|
37
|
+
attribute :xlink_title, :string
|
|
38
|
+
attribute :xlink_show, :string
|
|
39
|
+
attribute :xlink_actuate, :string
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Common attrs for simple text-with-id elements
|
|
45
|
+
module TextWithId
|
|
46
|
+
def self.included(base)
|
|
47
|
+
base.class_eval do
|
|
48
|
+
attribute :id, :string
|
|
49
|
+
attribute :content_type, :string
|
|
50
|
+
attribute :specific_use, :string
|
|
51
|
+
attribute :xml_lang, :string
|
|
52
|
+
attribute :content, :string, collection: true
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Then:
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
class Abbrev < Lutaml::Model::Serializable
|
|
65
|
+
include IsoSts::CommonAttributes::Xlink
|
|
66
|
+
# ... class-specific attrs
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Trade-off
|
|
71
|
+
|
|
72
|
+
**Pros**:
|
|
73
|
+
- DRY at the attribute-declaration level
|
|
74
|
+
- Single source of truth for common attribute sets
|
|
75
|
+
- Easier to evolve (rename `xml_lang` → `xml_lang_attr` once)
|
|
76
|
+
- Same pattern as `Mml::Base::CommonAttributes` in the mml gem
|
|
77
|
+
|
|
78
|
+
**Cons**:
|
|
79
|
+
- Adds indirection — readers must look at the module to know which attrs a
|
|
80
|
+
class has
|
|
81
|
+
- Mapping (`map_attribute "xml:lang", to: :xml_lang`) still needs to be
|
|
82
|
+
declared per class
|
|
83
|
+
- Risk of "module soup" if too many tiny modules are introduced
|
|
84
|
+
|
|
85
|
+
## Decision needed
|
|
86
|
+
|
|
87
|
+
This is a judgment call. The duplication today is annoying but not
|
|
88
|
+
critical. The mml gem's precedent suggests the pattern is viable.
|
|
89
|
+
|
|
90
|
+
Recommendation: **defer** until the namespace-coupling work (B.03, B.04)
|
|
91
|
+
is complete. Doing it now would create churn on classes that are about to
|
|
92
|
+
change anyway.
|
|
93
|
+
|
|
94
|
+
## How to apply (if approved)
|
|
95
|
+
|
|
96
|
+
1. Start with one module (XLink) — covers 5+ classes, lowest risk
|
|
97
|
+
2. Convert one class, run tests, repeat
|
|
98
|
+
3. Each conversion is its own commit (small, reviewable)
|
|
99
|
+
4. Stop if the indirection starts hurting readability
|
|
100
|
+
|
|
101
|
+
## Verification
|
|
102
|
+
|
|
103
|
+
- All existing specs still pass
|
|
104
|
+
- No spec needs to change (attribute-set assertions should be unchanged —
|
|
105
|
+
the module just provides the attribute declarations, the class still
|
|
106
|
+
exposes the same keys)
|
|
107
|
+
- Rubocop clean
|
|
108
|
+
|
|
109
|
+
## Anti-pattern note
|
|
110
|
+
|
|
111
|
+
This proposal does NOT introduce cross-namespace sharing. The modules
|
|
112
|
+
live in `Sts::IsoSts::CommonAttributes::*` and are only included into
|
|
113
|
+
`Sts::IsoSts::*` classes. NisoSts would have its own
|
|
114
|
+
`Sts::NisoSts::CommonAttributes::*` if it wants the same pattern. This
|
|
115
|
+
respects the ADR 2026-05-07.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# D.11: Docs and README refresh
|
|
2
|
+
|
|
3
|
+
**Status**: deferred. Low priority but accumulates debt.
|
|
4
|
+
**Estimated effort**: small.
|
|
5
|
+
|
|
6
|
+
## Problem
|
|
7
|
+
|
|
8
|
+
Several docs reference outdated state:
|
|
9
|
+
|
|
10
|
+
- `README.adoc` — likely doesn't mention 0.6.x features (V2/V3 MathML host
|
|
11
|
+
binding, the namespace-independence principle, the strengthened
|
|
12
|
+
anti-pattern enforcement)
|
|
13
|
+
- `CLAUDE.md` — gives architecture guidance but predates the 2026-05-07
|
|
14
|
+
ADR, the recent unification work, the TODO.finalize/ series, and the
|
|
15
|
+
new TODO.roadmap/
|
|
16
|
+
- `TODO.sts-refactor/` — mostly historical; the overview at
|
|
17
|
+
`00-overview.md` should link to `TODO.roadmap/00-overview.md` as the
|
|
18
|
+
current source of truth
|
|
19
|
+
- Cross-references between TODO docs use stale ref counts (e.g.,
|
|
20
|
+
"63→16" appears in some places even after PRs reduced it to 11)
|
|
21
|
+
|
|
22
|
+
## Plan
|
|
23
|
+
|
|
24
|
+
1. **README** — refresh to mention:
|
|
25
|
+
- The IsoSts/NisoSts independence contract
|
|
26
|
+
- How to construct documents (which Fn/DispQuote/BoxedText class to use)
|
|
27
|
+
- MathML host binding (V2 for IsoSts, V3 for NisoSts)
|
|
28
|
+
- Anti-pattern enforcement (link to `spec/anti_patterns_spec.rb`)
|
|
29
|
+
2. **CLAUDE.md** — refresh architecture section to reflect:
|
|
30
|
+
- The ADR 2026-05-07 (IsoSts/NisoSts independence)
|
|
31
|
+
- Current autoload conventions (no `require_relative`, no internal
|
|
32
|
+
`require`)
|
|
33
|
+
- The anti-pattern rules now enforced by spec
|
|
34
|
+
3. **TODO.sts-refactor/00-overview.md** — add a header noting that
|
|
35
|
+
`TODO.roadmap/` is the current source of truth; this directory is
|
|
36
|
+
retained for history
|
|
37
|
+
4. **Cross-reference cleanup** — search and update stale ref counts
|
|
38
|
+
across all TODO docs
|
|
39
|
+
|
|
40
|
+
## How to apply
|
|
41
|
+
|
|
42
|
+
- One PR with all doc updates
|
|
43
|
+
- Coordinate with any in-flight code PRs to avoid stale doc references
|
|
44
|
+
- Consider an ADR directory (`docs/adr/`) for the architectural decisions;
|
|
45
|
+
currently they're embedded in TODO docs which is fragile
|
|
46
|
+
|
|
47
|
+
## Verification
|
|
48
|
+
|
|
49
|
+
- All Markdown links resolve
|
|
50
|
+
- Code examples in docs still work (copy-paste runnable)
|
|
51
|
+
- No stale references to deleted classes (TbxIsoTml::Fn, TbxIsoTml::Math,
|
|
52
|
+
Sts::Mathml::Math, etc.)
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|---|------|----------|----------|--------------|
|
|
20
20
|
| 01 | `01-mathml-delegation.md` | Anti-Pattern Fix | DONE | — |
|
|
21
21
|
| 02 | `02-type-resolution.md` | Anti-Pattern Fix | DONE | — |
|
|
22
|
-
| 03 | `03-namespace-coupling.md` | Architecture | IN PROGRESS (63→
|
|
22
|
+
| 03 | `03-namespace-coupling.md` | Architecture | IN PROGRESS (63→6 refs) | 01, 02 |
|
|
23
23
|
| 04 | `04-register-versioning.md` | Architecture | HIGH | 01, 02 |
|
|
24
24
|
| 05 | `05-missing-elements.md` | Feature Gap | MOSTLY DONE | 04 |
|
|
25
25
|
| 06 | `06-missing-attributes.md` | Feature Gap | DONE | 04 |
|
|
@@ -166,7 +166,7 @@ grep -r "method_missing|respond_to_missing|Object.const_get|\.send" lib/
|
|
|
166
166
|
- ~~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
|
|
167
167
|
|
|
168
168
|
### Architectural Items (High Effort)
|
|
169
|
-
- `03-namespace-coupling.md` — IN PROGRESS: 63→
|
|
169
|
+
- `03-namespace-coupling.md` — IN PROGRESS: 63→6 IsoSts→NisoSts references
|
|
170
170
|
remaining (issue #40). ISOSTS.xsd governs content models and all non-`@id`
|
|
171
171
|
attributes; the `@id` follows the 86948b9 convention.
|
|
172
172
|
- `04-register-versioning.md` — Version the models via lutaml-model Registers
|
|
@@ -193,7 +193,7 @@ the **NISO** XSD and applied the result to IsoSts.
|
|
|
193
193
|
|
|
194
194
|
## Next Action
|
|
195
195
|
Two independent tracks:
|
|
196
|
-
1. Finish `03` — the
|
|
196
|
+
1. Finish `03` — the 6 remaining refs split across five recursive roots
|
|
197
197
|
(`ElementCitation`, `PersonGroup`, `Collab`, `Source`, `TermDisplay`) and
|
|
198
198
|
five child-bearing roots. `DispQuote` and `BoxedText` themselves are now
|
|
199
199
|
IsoSts classes. The first 15 high-reuse dependency leaves are modelled,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
**Priority**: HIGH
|
|
4
4
|
**Category**: Architecture
|
|
5
5
|
**Estimated Effort**: High
|
|
6
|
-
**Status**: Partially done — 63 →
|
|
6
|
+
**Status**: Partially done — 63 → 6 references (GitHub issue #40)
|
|
7
7
|
|
|
8
8
|
## Problem
|
|
9
9
|
|
|
@@ -16,7 +16,9 @@ from 63 to 16. The `IsoSts::DispQuote` / `IsoSts::BoxedText` addition then
|
|
|
16
16
|
reduced it from 16 to 13 (Body#disp_quote, Sec#disp_quote, Sec#boxed_text).
|
|
17
17
|
The `IsoSts::Attrib` addition then reduced it from 13 to 11
|
|
18
18
|
(Array#attrib, TableWrapFoot#attrib) and filled the omission in DispQuote /
|
|
19
|
-
BoxedText from PR #48.
|
|
19
|
+
BoxedText from PR #48. The License/TermHead/CustomMetaGroup closure then
|
|
20
|
+
reduced it from 11 to 6 (Permissions#license, DefList#term_head, and
|
|
21
|
+
IsoMeta/RegMeta/NatMeta#custom_meta_group).
|
|
20
22
|
|
|
21
23
|
## Content models from ISOSTS.xsd; `@id` from the 86948b9 convention
|
|
22
24
|
|
|
@@ -91,6 +93,10 @@ Non-`@id` attribute lists must be **generated** from the XSD, never hand-read:
|
|
|
91
93
|
`element-citation`, `overline`, `roman`, `sans-serif`, `alternatives`,
|
|
92
94
|
`private-char`, `chem-struct`, `mml:math`, `target`, `tbx:entailedTerm`)
|
|
93
95
|
tracked below.
|
|
96
|
+
- **License / TermHead / CustomMetaGroup closure added** — `License`,
|
|
97
|
+
`LicenseP`, `TermHead`, `CustomMetaGroup`, `CustomMeta`, `MetaName`, and
|
|
98
|
+
`MetaValue` modelled from ISOSTS.xsd. 5 refs (`Permissions#license`,
|
|
99
|
+
`DefList#term_head`, `IsoMeta/RegMeta/NatMeta#custom_meta_group`).
|
|
94
100
|
|
|
95
101
|
### Why classes and not plain `:string`
|
|
96
102
|
|
|
@@ -101,13 +107,15 @@ round-trip. For a scalar, `render_empty: :empty` recovers it; for a collection
|
|
|
101
107
|
to `[]`, destroying the information at parse time before any render option
|
|
102
108
|
applies. Content-only classes round-trip every case.
|
|
103
109
|
|
|
104
|
-
## Remaining —
|
|
110
|
+
## Remaining — 6 refs
|
|
105
111
|
|
|
106
112
|
**5 refs to 5 recursive roots**: `ElementCitation`, `PersonGroup`, `Collab`,
|
|
107
113
|
`Source`, `TermDisplay`. Each reaches the same 78–79-element
|
|
108
114
|
mutually-recursive core before existing IsoSts boundaries (`sec` → `p` →
|
|
109
|
-
`disp-quote` → `p`). `DispQuote`, `BoxedText`,
|
|
110
|
-
classes and no longer in
|
|
115
|
+
`disp-quote` → `p`). `DispQuote`, `BoxedText`, `Attrib`, `License`,
|
|
116
|
+
`TermHead`, and `CustomMetaGroup` are now IsoSts classes and no longer in
|
|
117
|
+
this list. The remaining 6 are the recursive roots — see
|
|
118
|
+
`TODO.roadmap/04-issue-40-recursive-roots.md` for the strategy.
|
|
111
119
|
|
|
112
120
|
**8 refs to 5 child-bearing roots**, now measured after the first dependency
|
|
113
121
|
layer: `attrib` (:1082) reaches 78 not-yet-modelled ISOSTS elements before
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sts
|
|
4
|
+
module IsoSts
|
|
5
|
+
class CustomMeta < Lutaml::Model::Serializable
|
|
6
|
+
attribute :id, :string
|
|
7
|
+
attribute :specific_use, :string
|
|
8
|
+
attribute :xml_lang, :string
|
|
9
|
+
attribute :xlink_type, :string
|
|
10
|
+
attribute :xlink_href, :string
|
|
11
|
+
attribute :xlink_role, :string
|
|
12
|
+
attribute :xlink_title, :string
|
|
13
|
+
attribute :xlink_show, :string
|
|
14
|
+
attribute :xlink_actuate, :string
|
|
15
|
+
attribute :meta_name, ::Sts::IsoSts::MetaName
|
|
16
|
+
attribute :meta_value, ::Sts::IsoSts::MetaValue
|
|
17
|
+
|
|
18
|
+
xml do
|
|
19
|
+
element "custom-meta"
|
|
20
|
+
ordered
|
|
21
|
+
|
|
22
|
+
map_attribute "id", to: :id
|
|
23
|
+
map_attribute "specific-use", to: :specific_use
|
|
24
|
+
map_attribute "xml:lang", to: :xml_lang
|
|
25
|
+
map_attribute "xlink:type", to: :xlink_type
|
|
26
|
+
map_attribute "xlink:href", to: :xlink_href
|
|
27
|
+
map_attribute "xlink:role", to: :xlink_role
|
|
28
|
+
map_attribute "xlink:title", to: :xlink_title
|
|
29
|
+
map_attribute "xlink:show", to: :xlink_show
|
|
30
|
+
map_attribute "xlink:actuate", to: :xlink_actuate
|
|
31
|
+
|
|
32
|
+
map_element "meta-name", to: :meta_name
|
|
33
|
+
map_element "meta-value", to: :meta_value
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sts
|
|
4
|
+
module IsoSts
|
|
5
|
+
class CustomMetaGroup < Lutaml::Model::Serializable
|
|
6
|
+
attribute :custom_meta, ::Sts::IsoSts::CustomMeta, collection: true
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
element "custom-meta-group"
|
|
10
|
+
ordered
|
|
11
|
+
|
|
12
|
+
map_element "custom-meta", to: :custom_meta
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/sts/iso_sts/def_list.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Sts
|
|
|
13
13
|
attribute :originator, :string
|
|
14
14
|
attribute :label, ::Sts::IsoSts::Label
|
|
15
15
|
attribute :title, ::Sts::IsoSts::Title
|
|
16
|
-
attribute :term_head, ::Sts::
|
|
16
|
+
attribute :term_head, ::Sts::IsoSts::TermHead
|
|
17
17
|
attribute :def_head, ::Sts::TbxIsoTml::Definition
|
|
18
18
|
attribute :def_item, ::Sts::IsoSts::DefItem, collection: true
|
|
19
19
|
attribute :def_list, ::Sts::IsoSts::DefList, collection: true
|
data/lib/sts/iso_sts/iso_meta.rb
CHANGED
|
@@ -19,7 +19,7 @@ module Sts
|
|
|
19
19
|
attribute :permissions, ::Sts::IsoSts::Permissions, collection: true
|
|
20
20
|
attribute :std_xref, ::Sts::IsoSts::StandardCrossReference,
|
|
21
21
|
collection: true
|
|
22
|
-
attribute :custom_meta_group, ::Sts::
|
|
22
|
+
attribute :custom_meta_group, ::Sts::IsoSts::CustomMetaGroup,
|
|
23
23
|
collection: true
|
|
24
24
|
attribute :meta_date, ::Sts::IsoSts::MetaDate, collection: true
|
|
25
25
|
attribute :pub_date, ::Sts::IsoSts::PubDate
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sts
|
|
4
|
+
module IsoSts
|
|
5
|
+
class License < Lutaml::Model::Serializable
|
|
6
|
+
attribute :license_type, :string
|
|
7
|
+
attribute :specific_use, :string
|
|
8
|
+
attribute :xml_lang, :string
|
|
9
|
+
attribute :xlink_type, :string
|
|
10
|
+
attribute :xlink_href, :string
|
|
11
|
+
attribute :xlink_role, :string
|
|
12
|
+
attribute :xlink_title, :string
|
|
13
|
+
attribute :xlink_show, :string
|
|
14
|
+
attribute :xlink_actuate, :string
|
|
15
|
+
attribute :license_p, ::Sts::IsoSts::LicenseP, collection: true
|
|
16
|
+
|
|
17
|
+
xml do
|
|
18
|
+
element "license"
|
|
19
|
+
ordered
|
|
20
|
+
|
|
21
|
+
map_attribute "license-type", to: :license_type
|
|
22
|
+
map_attribute "specific-use", to: :specific_use
|
|
23
|
+
map_attribute "xml:lang", to: :xml_lang
|
|
24
|
+
map_attribute "xlink:type", to: :xlink_type
|
|
25
|
+
map_attribute "xlink:href", to: :xlink_href
|
|
26
|
+
map_attribute "xlink:role", to: :xlink_role
|
|
27
|
+
map_attribute "xlink:title", to: :xlink_title
|
|
28
|
+
map_attribute "xlink:show", to: :xlink_show
|
|
29
|
+
map_attribute "xlink:actuate", to: :xlink_actuate
|
|
30
|
+
|
|
31
|
+
map_element "license-p", to: :license_p
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sts
|
|
4
|
+
module IsoSts
|
|
5
|
+
class LicenseP < Lutaml::Model::Serializable
|
|
6
|
+
attribute :id, :string
|
|
7
|
+
attribute :specific_use, :string
|
|
8
|
+
attribute :xml_lang, :string
|
|
9
|
+
attribute :content_type, :string
|
|
10
|
+
attribute :content, :string, collection: true
|
|
11
|
+
attribute :email, ::Sts::IsoSts::Email, collection: true
|
|
12
|
+
attribute :ext_link, ::Sts::IsoSts::ExtLink, collection: true
|
|
13
|
+
attribute :uri, ::Sts::IsoSts::Uri, collection: true
|
|
14
|
+
attribute :mixed_citation, ::Sts::IsoSts::MixedCitation, collection: true
|
|
15
|
+
attribute :std, ::Sts::IsoSts::Std, collection: true
|
|
16
|
+
attribute :bold, ::Sts::IsoSts::Bold, collection: true
|
|
17
|
+
attribute :italic, ::Sts::IsoSts::Italic, collection: true
|
|
18
|
+
attribute :monospace, ::Sts::IsoSts::Monospace, collection: true
|
|
19
|
+
attribute :num, ::Sts::IsoSts::Num, collection: true
|
|
20
|
+
attribute :sc, ::Sts::IsoSts::Sc, collection: true
|
|
21
|
+
attribute :strike, ::Sts::IsoSts::Strike, collection: true
|
|
22
|
+
attribute :underline, ::Sts::IsoSts::Underline, collection: true
|
|
23
|
+
attribute :inline_graphic, ::Sts::IsoSts::InlineGraphic, collection: true
|
|
24
|
+
attribute :inline_formula, ::Sts::IsoSts::InlineFormula, collection: true
|
|
25
|
+
attribute :abbrev, ::Sts::IsoSts::Abbrev, collection: true
|
|
26
|
+
attribute :milestone_end, ::Sts::IsoSts::MilestoneEnd, collection: true
|
|
27
|
+
attribute :milestone_start, ::Sts::IsoSts::MilestoneStart,
|
|
28
|
+
collection: true
|
|
29
|
+
attribute :named_content, ::Sts::IsoSts::NamedContent, collection: true
|
|
30
|
+
attribute :styled_content, ::Sts::IsoSts::StyledContent, collection: true
|
|
31
|
+
attribute :list, ::Sts::IsoSts::List, collection: true
|
|
32
|
+
attribute :def_list, ::Sts::IsoSts::DefList, collection: true
|
|
33
|
+
attribute :non_normative_note, ::Sts::IsoSts::NonNormativeNote,
|
|
34
|
+
collection: true
|
|
35
|
+
attribute :non_normative_example, ::Sts::IsoSts::NonNormativeExample,
|
|
36
|
+
collection: true
|
|
37
|
+
attribute :preformat, ::Sts::IsoSts::Preformat, collection: true
|
|
38
|
+
attribute :fig, ::Sts::IsoSts::Fig, collection: true
|
|
39
|
+
attribute :graphic, ::Sts::IsoSts::Graphic, collection: true
|
|
40
|
+
attribute :disp_formula, ::Sts::IsoSts::DispFormula, collection: true
|
|
41
|
+
attribute :disp_quote, ::Sts::IsoSts::DispQuote, collection: true
|
|
42
|
+
attribute :boxed_text, ::Sts::IsoSts::BoxedText, collection: true
|
|
43
|
+
attribute :fn, ::Sts::IsoSts::Fn, collection: true
|
|
44
|
+
attribute :xref, ::Sts::IsoSts::Xref, collection: true
|
|
45
|
+
attribute :std_ref, ::Sts::IsoSts::StdRef, collection: true
|
|
46
|
+
attribute :sub, ::Sts::IsoSts::Sub, collection: true
|
|
47
|
+
attribute :sup, ::Sts::IsoSts::Sup, collection: true
|
|
48
|
+
|
|
49
|
+
xml do # rubocop:disable Metrics/BlockLength
|
|
50
|
+
element "license-p"
|
|
51
|
+
mixed_content
|
|
52
|
+
|
|
53
|
+
map_attribute "id", to: :id
|
|
54
|
+
map_attribute "specific-use", to: :specific_use
|
|
55
|
+
map_attribute "xml:lang", to: :xml_lang
|
|
56
|
+
map_attribute "content-type", to: :content_type
|
|
57
|
+
|
|
58
|
+
map_content to: :content
|
|
59
|
+
map_element "email", to: :email
|
|
60
|
+
map_element "ext-link", to: :ext_link
|
|
61
|
+
map_element "uri", to: :uri
|
|
62
|
+
map_element "mixed-citation", to: :mixed_citation
|
|
63
|
+
map_element "std", to: :std
|
|
64
|
+
map_element "bold", to: :bold
|
|
65
|
+
map_element "italic", to: :italic
|
|
66
|
+
map_element "monospace", to: :monospace
|
|
67
|
+
map_element "num", to: :num
|
|
68
|
+
map_element "sc", to: :sc
|
|
69
|
+
map_element "strike", to: :strike
|
|
70
|
+
map_element "underline", to: :underline
|
|
71
|
+
map_element "inline-graphic", to: :inline_graphic
|
|
72
|
+
map_element "inline-formula", to: :inline_formula
|
|
73
|
+
map_element "abbrev", to: :abbrev
|
|
74
|
+
map_element "milestone-end", to: :milestone_end
|
|
75
|
+
map_element "milestone-start", to: :milestone_start
|
|
76
|
+
map_element "named-content", to: :named_content
|
|
77
|
+
map_element "styled-content", to: :styled_content
|
|
78
|
+
map_element "list", to: :list
|
|
79
|
+
map_element "def-list", to: :def_list
|
|
80
|
+
map_element "non-normative-note", to: :non_normative_note
|
|
81
|
+
map_element "non-normative-example", to: :non_normative_example
|
|
82
|
+
map_element "preformat", to: :preformat
|
|
83
|
+
map_element "fig", to: :fig
|
|
84
|
+
map_element "graphic", to: :graphic
|
|
85
|
+
map_element "disp-formula", to: :disp_formula
|
|
86
|
+
map_element "disp-quote", to: :disp_quote
|
|
87
|
+
map_element "boxed-text", to: :boxed_text
|
|
88
|
+
map_element "fn", to: :fn
|
|
89
|
+
map_element "xref", to: :xref
|
|
90
|
+
map_element "std-ref", to: :std_ref
|
|
91
|
+
map_element "sub", to: :sub
|
|
92
|
+
map_element "sup", to: :sup
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|