sts 0.6.1 → 0.6.3
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/.rubocop_todo.yml +2 -0
- data/TODO.finalize/00-overview.md +56 -0
- data/TODO.finalize/01-investigation-findings.md +39 -0
- data/TODO.finalize/02-delete-tbxisotml-fn-fngroup.md +20 -0
- data/TODO.finalize/03-repoint-isosts-call-sites.md +27 -0
- data/TODO.finalize/04-repoint-tbxisotml-call-sites.md +24 -0
- data/TODO.finalize/05-sts-regression-specs.md +27 -0
- data/TODO.finalize/06-lutaml-model-element-builder-fix.md +45 -0
- data/TODO.finalize/07-lutaml-model-specs.md +12 -0
- data/TODO.finalize/08-sts-ruby-pr.md +20 -0
- data/TODO.finalize/09-lutaml-model-pr.md +5 -0
- data/TODO.finalize/10-audit-other-duplicates.md +29 -0
- data/TODO.finalize/11-strengthen-anti-patterns-spec.md +24 -0
- data/TODO.sts-refactor/00-overview.md +22 -13
- data/TODO.sts-refactor/03-namespace-coupling.md +17 -15
- data/lib/sts/iso_sts/body.rb +2 -0
- data/lib/sts/iso_sts/bold.rb +1 -1
- data/lib/sts/iso_sts/copyright_holder.rb +6 -0
- data/lib/sts/iso_sts/copyright_statement.rb +6 -0
- data/lib/sts/iso_sts/copyright_year.rb +4 -0
- data/lib/sts/iso_sts/disp_formula.rb +1 -1
- data/lib/sts/iso_sts/doc_number.rb +4 -1
- data/lib/sts/iso_sts/doc_type.rb +4 -1
- data/lib/sts/iso_sts/edition.rb +6 -0
- data/lib/sts/iso_sts/ext_link.rb +10 -0
- data/lib/sts/iso_sts/fpage.rb +2 -0
- data/lib/sts/iso_sts/graphic.rb +10 -0
- data/lib/sts/iso_sts/ics.rb +4 -1
- data/lib/sts/iso_sts/inline_formula.rb +1 -1
- data/lib/sts/iso_sts/is_proof.rb +7 -2
- data/lib/sts/iso_sts/issue.rb +2 -0
- data/lib/sts/iso_sts/italic.rb +1 -1
- data/lib/sts/iso_sts/label.rb +4 -0
- data/lib/sts/iso_sts/lpage.rb +2 -0
- data/lib/sts/iso_sts/mixed_citation.rb +14 -2
- data/lib/sts/iso_sts/named_content.rb +2 -0
- data/lib/sts/iso_sts/originator.rb +4 -1
- data/lib/sts/iso_sts/page_range.rb +2 -0
- data/lib/sts/iso_sts/paragraph.rb +2 -2
- data/lib/sts/iso_sts/part_number.rb +4 -1
- data/lib/sts/iso_sts/proj_id.rb +4 -1
- data/lib/sts/iso_sts/pub_date.rb +2 -0
- data/lib/sts/iso_sts/pub_id.rb +2 -0
- data/lib/sts/iso_sts/release_version.rb +4 -1
- data/lib/sts/iso_sts/sdo.rb +4 -1
- data/lib/sts/iso_sts/sec.rb +2 -2
- data/lib/sts/iso_sts/secretariat.rb +4 -1
- data/lib/sts/iso_sts/standard.rb +2 -2
- data/lib/sts/iso_sts/std.rb +1 -1
- data/lib/sts/iso_sts/sub.rb +4 -0
- data/lib/sts/iso_sts/sup.rb +4 -0
- data/lib/sts/iso_sts/suppl_number.rb +4 -1
- data/lib/sts/iso_sts/suppl_type.rb +4 -1
- data/lib/sts/iso_sts/suppl_version.rb +4 -1
- data/lib/sts/iso_sts/td.rb +2 -2
- data/lib/sts/iso_sts/term.rb +1 -1
- data/lib/sts/iso_sts/term_sec.rb +1 -1
- data/lib/sts/iso_sts/th.rb +2 -2
- data/lib/sts/iso_sts/title.rb +4 -0
- data/lib/sts/iso_sts/underline.rb +2 -0
- data/lib/sts/iso_sts/uri.rb +2 -0
- data/lib/sts/iso_sts/urn.rb +4 -1
- data/lib/sts/iso_sts/version.rb +4 -1
- data/lib/sts/iso_sts/volume.rb +2 -0
- data/lib/sts/iso_sts/year.rb +2 -0
- data/lib/sts/tbx_iso_tml/definition.rb +1 -1
- data/lib/sts/tbx_iso_tml/note.rb +1 -1
- data/lib/sts/tbx_iso_tml/table_wrap_foot.rb +2 -2
- data/lib/sts/tbx_iso_tml/td.rb +1 -1
- data/lib/sts/tbx_iso_tml/term.rb +1 -1
- data/lib/sts/tbx_iso_tml/th.rb +1 -1
- data/lib/sts/tbx_iso_tml.rb +0 -2
- data/lib/sts/version.rb +1 -1
- metadata +13 -3
- data/lib/sts/tbx_iso_tml/fn.rb +0 -20
- data/lib/sts/tbx_iso_tml/fn_group.rb +0 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 27e3b4850a13bbff3b16e63ad2293589079e4c29b4f25d2fa120a797b9f6ff7c
|
|
4
|
+
data.tar.gz: 572e19d6b4e428dca7a277d836f73b6121627d094fd1d0e492ef0ba4b82b905c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab688a012341d43a0daa2a2b79d7e68b7e2b10a9e4ee4f30824d357e1c3329721ccfe6fe071e331265ca79de26dc6d9deb54ad269519bc1a6e164f38d76bbd41
|
|
7
|
+
data.tar.gz: 1cd96829661efa371b501e25dac9f56e5aeb9b6ba3cac72c5de47e1b6d6377c2193eaf29842c36ae68a70321796ceb06079671df81ed848d2805c66256aed3e4
|
data/.rubocop_todo.yml
CHANGED
|
@@ -70,6 +70,8 @@ RSpec/DescribeClass:
|
|
|
70
70
|
- 'spec/elements/new_elements_spec.rb'
|
|
71
71
|
- 'spec/elements/reference_models_spec.rb'
|
|
72
72
|
- 'spec/elements/structural_models_spec.rb'
|
|
73
|
+
- 'spec/fn_namespace_spec.rb'
|
|
74
|
+
- 'spec/mathml_version_spec.rb'
|
|
73
75
|
- 'spec/round_trip/reference_docs_spec.rb'
|
|
74
76
|
|
|
75
77
|
# Offense count: 1
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# sts-ruby + lutaml-model Finalization Plan
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-07-25
|
|
4
|
+
**Trigger**: User-reported `NoMethodError: paragraph` on `Sts::TbxIsoTml::Fn` nested inside `Sts::NisoSts::Back` (rice.xml e2e).
|
|
5
|
+
**Status**: PR #1 (sts-ruby dedup) in flight; PR #2 (lutaml-model) deferred per downstream maintainer feedback.
|
|
6
|
+
|
|
7
|
+
## Root Cause Summary
|
|
8
|
+
|
|
9
|
+
Two layered bugs:
|
|
10
|
+
|
|
11
|
+
1. **sts-ruby**: `Sts::TbxIsoTml::Fn` (Ruby attr `:p`) and `Sts::NisoSts::Fn` (Ruby attr `:paragraph`) are duplicate `<fn>` classes with conflicting Ruby attribute names. `TbxIsoTml::FnGroup` similarly duplicates `NisoSts::FnGroup`. Six `Fn`/`FnGroup` classes exist across three namespaces; only four are schema-correct.
|
|
12
|
+
2. **lutaml-model**: `Lutaml::Xml::TransformationSupport::ElementBuilder#create_nested_model_element` uses the rule's cached `child_transformation` (keyed on declared `attribute_type`) regardless of the value's actual class. When a caller assigns an unrelated `Serializable` to a typed slot, the wrong transformation is applied silently, producing confusing `NoMethodError`s.
|
|
13
|
+
|
|
14
|
+
The cache itself is correct (`transformation_key` includes `object_id`). The bug is in the dispatch logic.
|
|
15
|
+
|
|
16
|
+
## Architecture Decision (PR #1)
|
|
17
|
+
|
|
18
|
+
`<fn>` and `<fn-group>` are JATS / NISO STS elements (per ISOSTS.xsd and NISO-STS-extended-1.xsd). They are **not** TBX-ISO-TML elements (TBX-ISO-TML is ISO 30042, a terminology model). The presence of `TbxIsoTml::Fn` and `TbxIsoTml::FnGroup` is a misclassification — same pattern as the prior `TbxIsoTml::Math` removal in commit `9e977a5`. Remove them.
|
|
19
|
+
|
|
20
|
+
Per [[architecture-namespace-independence]]:
|
|
21
|
+
- `IsoSts::*` references use `IsoSts::Fn` / `IsoSts::FnGroup` (independence from NisoSts).
|
|
22
|
+
- `NisoSts::*` references continue to use `NisoSts::Fn` / `NisoSts::FnGroup`.
|
|
23
|
+
- `TbxIsoTml::*` references follow the existing `TbxIsoTml::Bold` / `TbxIsoTml::Italic` precedent (both already use `NisoSts::Fn`): use `NisoSts::Fn` / `NisoSts::FnGroup`. TBX is a shared namespace.
|
|
24
|
+
|
|
25
|
+
## Decision: Defer PR #2 (lutaml-model)
|
|
26
|
+
|
|
27
|
+
Downstream metanorma-iso maintainer reviewed the plan and recommended defer:
|
|
28
|
+
> #2 is a real robustness win but introduces a new contract that may break
|
|
29
|
+
> other downstream consumers who've been quietly relying on the current
|
|
30
|
+
> lenient behavior. Worth doing eventually, but urgency drops once #1 lands.
|
|
31
|
+
|
|
32
|
+
Once #1 lands, the trap cannot be triggered via the original repo's classes. The lenient dispatch remains a robustness gap for future duplicates — see TODO 10 (audit other potential duplicates).
|
|
33
|
+
|
|
34
|
+
## Execution Order
|
|
35
|
+
|
|
36
|
+
| # | File | Status |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| 01 | investigation findings | complete |
|
|
39
|
+
| 02 | delete `TbxIsoTml::Fn` / `TbxIsoTml::FnGroup` | complete |
|
|
40
|
+
| 03 | repoint IsoSts call sites to `IsoSts::Fn` | complete |
|
|
41
|
+
| 04 | repoint TbxIsoTml call sites to `NisoSts::Fn` | complete |
|
|
42
|
+
| 05 | sts-ruby regression specs | complete |
|
|
43
|
+
| 06 | lutaml-model `ElementBuilder` dispatch fix | **deferred** |
|
|
44
|
+
| 07 | lutaml-model specs | **deferred** |
|
|
45
|
+
| 08 | sts-ruby PR | in flight |
|
|
46
|
+
| 09 | lutaml-model PR | **deferred** |
|
|
47
|
+
| 10 | audit other potential duplicates | deferred (future) |
|
|
48
|
+
| 11 | strengthen `anti_patterns_spec.rb` | deferred (future) |
|
|
49
|
+
|
|
50
|
+
## Principles enforced (PR #1)
|
|
51
|
+
|
|
52
|
+
- **MECE**: each Fn class lives in exactly one namespace; no parallel hierarchies.
|
|
53
|
+
- **Model-driven**: every `<fn>` reference is a typed `attribute :fn, ::Sts::<Namespace>::Fn`.
|
|
54
|
+
- **OCP**: adding a new host namespace = adding new Fn classes there, not editing existing ones.
|
|
55
|
+
- **DRY**: one class per (namespace, XML element) pair.
|
|
56
|
+
- **No anti-patterns**: no `send`, no `instance_variable_set/get`, no `respond_to?`, no `require_relative` in lib.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# 01: Investigation Findings — Fn/FnGroup Duplication
|
|
2
|
+
|
|
3
|
+
**Status**: complete (findings documented for reference)
|
|
4
|
+
|
|
5
|
+
## Six classes discovered
|
|
6
|
+
|
|
7
|
+
| Class | File | Ruby attr for `<p>` | Other notable attrs |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `Sts::IsoSts::Fn` | `lib/sts/iso_sts/fn.rb` | `:paragraph` | fn_type, specific_use, symbol, xml_lang, non_normative_note, non_normative_example |
|
|
10
|
+
| `Sts::IsoSts::FnGroup` | `lib/sts/iso_sts/fn_group.rb` | — | content_type, specific_use, xml_lang, originator, label, title |
|
|
11
|
+
| `Sts::NisoSts::Fn` | `lib/sts/niso_sts/fn.rb` | `:paragraph` | (minimal) |
|
|
12
|
+
| `Sts::NisoSts::FnGroup` | `lib/sts/niso_sts/fn_group.rb` | — | (minimal) |
|
|
13
|
+
| `Sts::TbxIsoTml::Fn` | `lib/sts/tbx_iso_tml/fn.rb` | `:p` ← **outlier** | (minimal) |
|
|
14
|
+
| `Sts::TbxIsoTml::FnGroup` | `lib/sts/tbx_iso_tml/fn_group.rb` | — | (minimal) |
|
|
15
|
+
|
|
16
|
+
## Call sites (24 total)
|
|
17
|
+
|
|
18
|
+
### IsoSts (8 sites — all wrong, should be IsoSts::Fn)
|
|
19
|
+
- `lib/sts/iso_sts/{td,bold,paragraph,mixed_citation,sec,th,std,italic}.rb`
|
|
20
|
+
|
|
21
|
+
### IsoSts (correct — already uses IsoSts::Fn/IsoSts::FnGroup)
|
|
22
|
+
- `lib/sts/iso_sts/{fig,table_wrap_foot,fn_group,app,back,term_sec}.rb`
|
|
23
|
+
|
|
24
|
+
### TbxIsoTml (4 sites — should be NisoSts::Fn following Bold/Italic pattern)
|
|
25
|
+
- `lib/sts/tbx_iso_tml/{td,th,table_wrap_foot,fn_group}.rb`
|
|
26
|
+
|
|
27
|
+
### TbxIsoTml (correct — already uses NisoSts::Fn)
|
|
28
|
+
- `lib/sts/tbx_iso_tml/{bold,italic}.rb`
|
|
29
|
+
|
|
30
|
+
### NisoSts (correct — uses NisoSts::Fn/NisoSts::FnGroup)
|
|
31
|
+
- `lib/sts/niso_sts/{author_notes,source,data_title,named_content,mixed_citation,paragraph,section,back,display_formula,role,reference_standard,contrib,styled_content,toc,boxed_text,fn_group}.rb`
|
|
32
|
+
|
|
33
|
+
## Verification of root cause
|
|
34
|
+
|
|
35
|
+
Patch on `Lutaml::Xml::Transformation#apply_standard_rules` showed: when `Sts::TbxIsoTml::Fn` is serialized inside a `Sts::NisoSts::Back` (whose `:fn_group` is typed `NisoSts::FnGroup`), the transformation applied has `model_class = Sts::NisoSts::Fn` (not `TbxIsoTml::Fn`). Its compiled rules include `attribute_name=:paragraph`, which is then `public_send`-ed on the TbxIsoTml::Fn value, raising `NoMethodError`.
|
|
36
|
+
|
|
37
|
+
The reverse also fails: `NisoSts::Fn` inside `TbxIsoTml::FnGroup` raises `private method 'p' called`.
|
|
38
|
+
|
|
39
|
+
The cache key in `TransformationRegistry#transformation_key` includes `object_id`, so cache collision is NOT the cause. The bug is in `ElementBuilder#create_nested_model_element` — it reuses `rule.child_transformation` (cached at compile time for the declared `attribute_type`) without consulting `value.class`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 02: Delete `Sts::TbxIsoTml::Fn` and `Sts::TbxIsoTml::FnGroup`
|
|
2
|
+
|
|
3
|
+
**Status**: pending
|
|
4
|
+
**Blocks**: 03, 04, 05
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
`<fn>` and `<fn-group>` are JATS / NISO STS elements. They are not defined by TBX-ISO-TML (ISO 30042). The `TbxIsoTml::Fn` and `TbxIsoTml::FnGroup` classes are misclassified duplicates of `NisoSts::Fn` / `NisoSts::FnGroup` with one schema-breaking difference: the Ruby attribute for `<p>` is `:p` in TbxIsoTml and `:paragraph` in every other namespace. This mismatch is the root cause of the user-reported `NoMethodError`.
|
|
9
|
+
|
|
10
|
+
## Actions
|
|
11
|
+
|
|
12
|
+
- [x] Delete `lib/sts/tbx_iso_tml/fn.rb`
|
|
13
|
+
- [x] Delete `lib/sts/tbx_iso_tml/fn_group.rb`
|
|
14
|
+
- [x] Remove `autoload :Fn` and `autoload :FnGroup` from `lib/sts/tbx_iso_tml.rb`
|
|
15
|
+
- [x] Run `bundle exec rspec` — confirm no spec references the deleted constants
|
|
16
|
+
|
|
17
|
+
## Verification
|
|
18
|
+
|
|
19
|
+
- `grep -rn "TbxIsoTml::Fn\b\|TbxIsoTml::FnGroup\b" lib/ spec/` returns nothing after steps 03 and 04 complete.
|
|
20
|
+
- `Sts::TbxIsoTml.const_defined?(:Fn)` is `false`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 03: Repoint IsoSts call sites to `IsoSts::Fn`
|
|
2
|
+
|
|
3
|
+
**Status**: pending
|
|
4
|
+
**Blocked by**: 02
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
Per [[architecture-namespace-independence]], `IsoSts` must be independent of `NisoSts`. The 8 IsoSts files that currently reference `TbxIsoTml::Fn` violate this. They should reference `IsoSts::Fn`, which already exists with the correct ISOSTS schema (5 attributes + label + paragraph + non_normative_note + non_normative_example).
|
|
9
|
+
|
|
10
|
+
## Actions
|
|
11
|
+
|
|
12
|
+
For each file, swap `::Sts::TbxIsoTml::Fn` → `::Sts::IsoSts::Fn`:
|
|
13
|
+
|
|
14
|
+
- [x] `lib/sts/iso_sts/td.rb:28`
|
|
15
|
+
- [x] `lib/sts/iso_sts/bold.rb:25`
|
|
16
|
+
- [x] `lib/sts/iso_sts/paragraph.rb:27`
|
|
17
|
+
- [x] `lib/sts/iso_sts/mixed_citation.rb:22`
|
|
18
|
+
- [x] `lib/sts/iso_sts/sec.rb:37`
|
|
19
|
+
- [x] `lib/sts/iso_sts/th.rb:28`
|
|
20
|
+
- [x] `lib/sts/iso_sts/std.rb:14`
|
|
21
|
+
- [x] `lib/sts/iso_sts/italic.rb:25`
|
|
22
|
+
|
|
23
|
+
## Verification
|
|
24
|
+
|
|
25
|
+
- `grep -rn "TbxIsoTml::Fn\b" lib/sts/iso_sts/` returns nothing.
|
|
26
|
+
- `bundle exec rspec spec/iso_sts/` is green.
|
|
27
|
+
- Full suite green (no spec depends on the old typing).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# 04: Repoint TbxIsoTml call sites to `NisoSts::Fn`
|
|
2
|
+
|
|
3
|
+
**Status**: pending
|
|
4
|
+
**Blocked by**: 02
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
After step 02 deletes `TbxIsoTml::Fn` / `TbxIsoTml::FnGroup`, the 4 TbxIsoTml files that referenced them must point somewhere. Following the established `TbxIsoTml::Bold` / `TbxIsoTml::Italic` precedent (both already use `NisoSts::Fn`), use `NisoSts::Fn` / `NisoSts::FnGroup`.
|
|
9
|
+
|
|
10
|
+
TBX-ISO-TML is a shared namespace (per [[architecture-namespace-independence]]: "independence from NisoSts is not independence in general"). `<fn>` inside a TBX table cell is a NISO STS element borrowed into TBX context, so the NISO STS type is the correct reference.
|
|
11
|
+
|
|
12
|
+
## Actions
|
|
13
|
+
|
|
14
|
+
- [x] `lib/sts/tbx_iso_tml/td.rb:94` — `::Sts::TbxIsoTml::Fn` → `::Sts::NisoSts::Fn`
|
|
15
|
+
- [x] `lib/sts/tbx_iso_tml/th.rb:95` — same
|
|
16
|
+
- [x] `lib/sts/tbx_iso_tml/table_wrap_foot.rb:7` — `::Sts::TbxIsoTml::FnGroup` → `::Sts::NisoSts::FnGroup`
|
|
17
|
+
- [x] `lib/sts/tbx_iso_tml/table_wrap_foot.rb:13` — `::Sts::TbxIsoTml::Fn` → `::Sts::NisoSts::Fn`
|
|
18
|
+
|
|
19
|
+
`lib/sts/tbx_iso_tml/fn_group.rb` is deleted in step 02 — no repoint needed.
|
|
20
|
+
|
|
21
|
+
## Verification
|
|
22
|
+
|
|
23
|
+
- `grep -rn "TbxIsoTml::Fn\b\|TbxIsoTml::FnGroup\b" lib/sts/tbx_iso_tml/` returns nothing.
|
|
24
|
+
- `bundle exec rspec` green.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 05: Add sts-ruby regression specs
|
|
2
|
+
|
|
3
|
+
**Status**: pending
|
|
4
|
+
**Blocked by**: 02, 03, 04
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
Round-tripping alone cannot catch this class of bug — the wrong-type assignment only fails when nested two levels deep, and a future contributor could re-introduce `TbxIsoTml::Fn` thinking it is a reasonable place for a TBX footnote. Specs must assert:
|
|
9
|
+
|
|
10
|
+
1. The deleted constants stay deleted.
|
|
11
|
+
2. Each call site uses the correct namespace's Fn.
|
|
12
|
+
3. The original bug repro (NisoSts::Back wrapping TbxIsoTml-style Fn usage) no longer raises — but this is now impossible to express directly because TbxIsoTml::Fn is gone. Instead, assert that a NisoSts::Back → NisoSts::FnGroup → NisoSts::Fn serialization round-trips, and the original error message ("undefined method 'paragraph'") cannot occur.
|
|
13
|
+
|
|
14
|
+
## Actions
|
|
15
|
+
|
|
16
|
+
- [x] Add `spec/fn_namespace_spec.rb` asserting:
|
|
17
|
+
- `Sts::TbxIsoTml.const_defined?(:Fn)` is `false`
|
|
18
|
+
- `Sts::TbxIsoTml.const_defined?(:FnGroup)` is `false`
|
|
19
|
+
- `lib/sts/iso_sts/**/*.rb` files reference `IsoSts::Fn` / `IsoSts::FnGroup`, never `TbxIsoTml::Fn`
|
|
20
|
+
- `lib/sts/tbx_iso_tml/**/*.rb` files reference `NisoSts::Fn` / `NisoSts::FnGroup`, never `TbxIsoTml::Fn`
|
|
21
|
+
- Cross-namespace `Fn`/`FnGroup` instantiation and round-trip works through `NisoSts::Back → NisoSts::FnGroup → NisoSts::Fn`
|
|
22
|
+
- [x] Run full suite, confirm green.
|
|
23
|
+
|
|
24
|
+
## Verification
|
|
25
|
+
|
|
26
|
+
- New spec file passes (14+ examples).
|
|
27
|
+
- Full suite: 2300+ examples, 0 failures.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# 06: lutaml-model `ElementBuilder#create_nested_model_element` dispatch fix
|
|
2
|
+
|
|
3
|
+
**Status**: DEFERRED (per downstream maintainer feedback 2026-07-25)
|
|
4
|
+
**Repo**: `lutaml/lutaml-model`
|
|
5
|
+
**File**: `lib/lutaml/xml/transformation/element_builder.rb`
|
|
6
|
+
|
|
7
|
+
## Why deferred
|
|
8
|
+
|
|
9
|
+
The downstream metanorma-iso maintainer (who originally reported the bug) reviewed the proposed two-PR plan and recommended:
|
|
10
|
+
|
|
11
|
+
> Defer #2. The fix is a real robustness win but introduces a new contract
|
|
12
|
+
> ("declared type must match value class") that may break other downstream
|
|
13
|
+
> consumers who've been quietly relying on the current lenient behavior. Worth
|
|
14
|
+
> doing eventually, but the urgency drops once #1 lands — without the
|
|
15
|
+
> duplicate classes there's no easy way to trigger the trap.
|
|
16
|
+
|
|
17
|
+
## Original analysis (kept for future reference)
|
|
18
|
+
|
|
19
|
+
Currently `create_nested_model_element` reuses `rule.child_transformation` (compiled for the declared `attribute_type`) for any value that is not a declared subtype. When a caller assigns an unrelated `Lutaml::Model::Serialize` to a typed slot, the wrong transformation is applied to the value, producing confusing `NoMethodError`s on whichever Ruby attribute name differs.
|
|
20
|
+
|
|
21
|
+
The cache itself is fine — `transformation_key` includes `object_id`. The dispatch logic is the bug.
|
|
22
|
+
|
|
23
|
+
## When to revisit
|
|
24
|
+
|
|
25
|
+
- Track upstream consumers: if a second case of cross-class assignment emerges (e.g., another gem duplicates a Serializable with different Ruby attribute names), the urgency rises.
|
|
26
|
+
- Pair with a proper audit of existing polymorphic specs to ensure the lenient dispatch wouldn't break tests.
|
|
27
|
+
- Consider an opt-in flag (`strict_type_check: true`) before flipping default behavior.
|
|
28
|
+
|
|
29
|
+
## Sketch of the fix (when revisited)
|
|
30
|
+
|
|
31
|
+
In `lib/lutaml/xml/transformation/element_builder.rb#create_nested_model_element`:
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
dispatch_on_value_class = union || is_polymorphic ||
|
|
35
|
+
(value.is_a?(Lutaml::Model::Serialize) && value.class != rule.attribute_type)
|
|
36
|
+
|
|
37
|
+
child_transformation = if dispatch_on_value_class
|
|
38
|
+
value.class.transformation_for(:xml, register)
|
|
39
|
+
else
|
|
40
|
+
rule.child_transformation ||
|
|
41
|
+
rule.attribute_type.transformation_for(:xml, register)
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This subsumes the existing `is_polymorphic_subtype` check (subtypes already have `value.class != rule.attribute_type`).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# 07: lutaml-model specs for cross-class dispatch
|
|
2
|
+
|
|
3
|
+
**Status**: DEFERRED (follows step 06)
|
|
4
|
+
|
|
5
|
+
See step 06 for the deferral rationale. When 06 is revisited, the specs described below should accompany it.
|
|
6
|
+
|
|
7
|
+
## Originally planned specs
|
|
8
|
+
|
|
9
|
+
- Cross-class dispatch: parent declares `attribute :child, ParentClass`; caller assigns `OtherSerializable.new` (not a subtype). Serialization uses `OtherSerializable`'s mapping rules.
|
|
10
|
+
- Round-trip preserved: parsing the serialized XML yields an instance whose attributes match the original.
|
|
11
|
+
- Declared-type fast path unchanged: assigning a `ParentClass` instance uses the cached `child_transformation`.
|
|
12
|
+
- Subtype polymorphism (existing `is_polymorphic_subtype` behaviour) still works.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 08: Open sts-ruby PR
|
|
2
|
+
|
|
3
|
+
**Status**: pending
|
|
4
|
+
**Blocked by**: 02, 03, 04, 05
|
|
5
|
+
|
|
6
|
+
## Actions
|
|
7
|
+
|
|
8
|
+
- [x] Branch `fix/remove-tbxisotml-fn-duplicate` off latest `main`.
|
|
9
|
+
- [x] Commit steps 02–05 with a clear message.
|
|
10
|
+
- [x] Push, open PR against `metanorma/sts-ruby`.
|
|
11
|
+
- [x] PR body via `--body-file` (contains backticks — never inline).
|
|
12
|
+
|
|
13
|
+
## PR description points
|
|
14
|
+
|
|
15
|
+
- Root cause: duplicate `<fn>` classes across namespaces with conflicting Ruby attr names.
|
|
16
|
+
- Why TbxIsoTml loses its Fn/FnGroup: `<fn>` is not a TBX-ISO-TML element.
|
|
17
|
+
- Why IsoSts keeps its own: namespace independence (per ADR 2026-05-07).
|
|
18
|
+
- Why TbxIsoTml call sites use NisoSts::Fn: matches existing Bold/Italic pattern; TBX is shared.
|
|
19
|
+
- Behaviour change: callers that construct IsoSts documents using `TbxIsoTml::Fn` must now use `IsoSts::Fn` (drop-in: same `:paragraph` Ruby attr).
|
|
20
|
+
- References TODO.finalize/00-overview.md.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# 10: Audit other potential duplicates (deferred)
|
|
2
|
+
|
|
3
|
+
**Status**: deferred — track for future investigation
|
|
4
|
+
**Priority**: medium
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
The Fn/FnGroup duplication suggests `TbxIsoTml` may contain other JATS / NISO STS elements misclassified as TBX. Each duplicate is a potential version-mismatch footgun. A one-time audit would surface them.
|
|
9
|
+
|
|
10
|
+
## Suspects to investigate
|
|
11
|
+
|
|
12
|
+
Cross-reference each `TbxIsoTml::*` class against the TBX-ISO-TML (ISO 30042) element list. Anything NOT in TBX-ISO-TML is a misfit. Likely candidates:
|
|
13
|
+
|
|
14
|
+
- `TbxIsoTml::Xref` — `<xref>` is a JATS element
|
|
15
|
+
- `TbxIsoTml::TableWrap` — `<table-wrap>` is JATS / NISO STS
|
|
16
|
+
- `TbxIsoTml::Table`, `TbxIsoTml::Thead`, `TbxIsoTml::Tbody`, `TbxIsoTml::Tfoot`, `TbxIsoTml::Tr`, `TbxIsoTml::Th`, `TbxIsoTml::Td`, `TbxIsoTml::Col`, `TbxIsoTml::Colgroup` — XHTML table model, not TBX
|
|
17
|
+
- `TbxIsoTml::Caption` — `<caption>` is JATS
|
|
18
|
+
- `TbxIsoTml::FnGroup` (deleted in step 02)
|
|
19
|
+
- `TbxIsoTml::List` (if present) — `<list>` is JATS
|
|
20
|
+
|
|
21
|
+
True TBX-ISO-TML elements (must stay): `TermEntry`, `Tig`, `Term`, `TermInformationGroup`, `EntailedTerm`, `Descrip`, `DescripGrp`, `Note` (TBX-spec note, not JATS note), `Definition`, `Source`, `LangSet`, `SubjectField`, `PartOfSpeech`, etc.
|
|
22
|
+
|
|
23
|
+
## Verification approach for each suspect
|
|
24
|
+
|
|
25
|
+
1. Check ISO 30042 / TBX-INFO documentation for the element name.
|
|
26
|
+
2. If NOT in TBX-ISO-TML: should not exist in `Sts::TbxIsoTml::*`.
|
|
27
|
+
3. Decide: delete (if no semantic difference from the JATS / NISO STS equivalent) or move to the correct namespace.
|
|
28
|
+
|
|
29
|
+
This is **not** in scope for the current PR series. Track as a follow-up.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# 11: Strengthen `anti_patterns_spec.rb` (deferred)
|
|
2
|
+
|
|
3
|
+
**Status**: deferred — track for future improvement
|
|
4
|
+
**Priority**: low
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
The current `spec/anti_patterns_spec.rb` checks for `method_missing`, `respond_to_missing?`, `Object.const_get`, `.send(` — but misses several global-rule patterns. The MathML hack file (`lib/sts/iso_sts/mathml2/math.rb`, since deleted in TODO 02 of the prior audit) had `instance_variable_set`, `respond_to?(:read)`, and hand-rolled `to_xml` — none would have been caught.
|
|
9
|
+
|
|
10
|
+
## Add checks for
|
|
11
|
+
|
|
12
|
+
- [ ] `instance_variable_set` / `instance_variable_get` (forbidden by global rule)
|
|
13
|
+
- [ ] `respond_to?` for type-checking (allowed only inside test infrastructure or explicit adapter negotiation — define an allowlist)
|
|
14
|
+
- [ ] Hand-rolled serialization methods on `Lutaml::Model::Serializable` subclasses: `def to_h`, `def to_hash`, `def from_h`, `def from_hash`, `def to_json`, `def from_json`, `def to_xml`, `def from_xml`, `def serialize`, `def deserialize`
|
|
15
|
+
- [ ] `require_relative` anywhere in `lib/` (autoloads only — global rule)
|
|
16
|
+
- [ ] `double(` in specs (global rule)
|
|
17
|
+
|
|
18
|
+
## Implementation notes
|
|
19
|
+
|
|
20
|
+
- The existing pattern (file-by-file source scan) extends naturally — add new `it` blocks per check.
|
|
21
|
+
- Some checks may need an allowlist (e.g., `respond_to?` for IO vs String detection at gem boundaries). Document the allowlist inline.
|
|
22
|
+
- Run after every lib change, not just at PR time.
|
|
23
|
+
|
|
24
|
+
This is **not** in scope for the current PR series. Track as a follow-up.
|
|
@@ -167,26 +167,35 @@ grep -r "method_missing|respond_to_missing|Object.const_get|\.send" lib/
|
|
|
167
167
|
|
|
168
168
|
### Architectural Items (High Effort)
|
|
169
169
|
- `03-namespace-coupling.md` — IN PROGRESS: 63→20 IsoSts→NisoSts references
|
|
170
|
-
remaining (issue #40).
|
|
171
|
-
|
|
170
|
+
remaining (issue #40). ISOSTS.xsd governs content models and all non-`@id`
|
|
171
|
+
attributes; the `@id` follows the 86948b9 convention.
|
|
172
172
|
- `04-register-versioning.md` — Version the models via lutaml-model Registers
|
|
173
173
|
- `11-duplicate-models.md` — 44 overlapping element resolution (depends on 03)
|
|
174
174
|
|
|
175
|
-
###
|
|
175
|
+
### Schema conformance — dropped ISOSTS attributes
|
|
176
176
|
The 2026-05-07 "@id added to all models (XSD-verified)" pass verified against
|
|
177
|
-
the **NISO** XSD and applied the result to IsoSts.
|
|
178
|
-
- **
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
`
|
|
182
|
-
|
|
183
|
-
-
|
|
184
|
-
|
|
177
|
+
the **NISO** XSD and applied the result to IsoSts.
|
|
178
|
+
- **Fixed — dropped ISOSTS attributes restored.** 15 IsoSts models were
|
|
179
|
+
silently dropping ISOSTS attributes present in real documents (data loss):
|
|
180
|
+
`sub`/`sup` (`arrange`+`specific-use`), `ext-link`/`mixed-citation`/`uri`/
|
|
181
|
+
`named-content` (`xlink:*`), `graphic` (`xlink:*`+`originator`), `copyright-*`,
|
|
182
|
+
`edition`, `title`, `label`, `underline`, `body`. This change adds them and
|
|
183
|
+
fixes `sec`/`standard`/`term-sec`, which mapped `xml:lang` under the wrong XML
|
|
184
|
+
name. (`meta-date` was NOT lossy — it already maps `type`.)
|
|
185
|
+
- **Not a bug — the conventional `@id`.** IsoSts models carry an `@id` that
|
|
186
|
+
ISOSTS does not itself define; this is the deliberate 86948b9 convention
|
|
187
|
+
(NISO-XSD-verified), not dead surface.
|
|
188
|
+
- **Remaining follow-up (separate change).** 7 spurious attributes on 5 models
|
|
189
|
+
(model carries an attr ISOSTS does not define: `graphic` `type`, `body`/`back`
|
|
190
|
+
`content-type`, `content-language`/`language` extras), and the 6 classes left
|
|
191
|
+
without `@id` in 86948b9 (`monospace`, `sc`, `strike`, `underline`, `uri`,
|
|
192
|
+
`standard_ref`).
|
|
185
193
|
|
|
186
194
|
## Next Action
|
|
187
195
|
Two independent tracks:
|
|
188
196
|
1. Finish `03` — the 20 remaining refs split into 11 deep-root refs (each
|
|
189
197
|
reaching a ~152-class recursive core) and 9 child-bearing refs whose closure
|
|
190
198
|
is unmeasured. Both need sizing before planning.
|
|
191
|
-
2.
|
|
192
|
-
|
|
199
|
+
2. The remaining schema-conformance follow-up above — the 7 spurious attributes
|
|
200
|
+
on 5 models and the 6 classes without `@id`. (The dropped-attribute data loss
|
|
201
|
+
is now fixed.)
|
|
@@ -14,41 +14,42 @@ evolves, so coupling them violates OCP.
|
|
|
14
14
|
PR #31 reduced this from 157 to 63 references. Issue #40 reduced it further,
|
|
15
15
|
from 63 to 20.
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Content models from ISOSTS.xsd; `@id` from the 86948b9 convention
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
`
|
|
19
|
+
IsoSts models carry `@id` following the compatibility convention established in
|
|
20
|
+
86948b9 (NISO-XSD-verified). ISOSTS.xsd governs element content
|
|
21
|
+
models and all non-`@id` attributes; it is not an authority that forbids the
|
|
22
|
+
conventional `@id`. So the two schemas can legitimately differ per element:
|
|
22
23
|
|
|
23
|
-
| Element | ISOSTS
|
|
24
|
+
| Element | ISOSTS content/attrs | NisoSts model |
|
|
24
25
|
|---|---|---|
|
|
25
|
-
| `
|
|
26
|
-
| `doc-type` (:6378) | `type="xs:string"` — no attributes at all | `@id` + content |
|
|
26
|
+
| `doc-type` (:6378) | `type="xs:string"` | `@id` + content |
|
|
27
27
|
| `ics` (:6373) | `type="xs:string"` | `@id` + `ics-desc` child |
|
|
28
28
|
| `fpage` | `content-type`, `seq`, `specific-use`, `xml:lang`; no children | `@id` + bold/italic |
|
|
29
29
|
| `license` (:51) | `license-type`, `specific-use`, `xml:lang` | `@id`, `xlink:href` |
|
|
30
|
-
| `ruby` | **not an ISOSTS element** | exists (NISO only) |
|
|
31
30
|
|
|
32
31
|
`feature_doc.xml` declares `<!DOCTYPE standard SYSTEM ".../ISOSTS.dtd">`, and
|
|
33
32
|
the ISOSTS DTD agrees with ISOSTS.xsd (both derive `bold`, `sub` etc. from the
|
|
34
|
-
JATS 0.4 modules)
|
|
33
|
+
JATS 0.4 modules) on content models.
|
|
35
34
|
|
|
36
35
|
**Round-tripping does not prove correctness.** A model that invents or drops an
|
|
37
36
|
attribute still parses and serialises symmetrically, so the suite stays green
|
|
38
37
|
while the model is wrong. Assert the exact attribute set per element instead.
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
on `tex-math` and `specific-use` on `pub-id` sit after long
|
|
42
|
-
blocks and are invisible to a truncated read.
|
|
39
|
+
Non-`@id` attribute lists must be **generated** from the XSD, never hand-read:
|
|
40
|
+
`version` on `tex-math` and `specific-use` on `pub-id` sit after long
|
|
41
|
+
`xs:enumeration` blocks and are invisible to a truncated read.
|
|
43
42
|
|
|
44
43
|
## Done in issue #40 — 43 refs removed, 27 classes added
|
|
45
44
|
|
|
46
45
|
- **14 `xs:string` elements** (`originator`, `doc-type`, `doc-number`,
|
|
47
46
|
`part-number`, `version`, `suppl-type`, `suppl-number`, `suppl-version`,
|
|
48
47
|
`urn`, `sdo`, `proj-id`, `release-version`, `ics`, `secretariat`) — modelled
|
|
49
|
-
as content
|
|
48
|
+
as content IsoSts classes that also carry the conventional `@id` (86948b9);
|
|
49
|
+
`secretariat` is content plus `@id`, not content-only. 23 refs.
|
|
50
50
|
- **3 `permissions` refs** repointed to the existing `IsoSts::Permissions`.
|
|
51
|
-
- **`ruby` deleted** from `StyledContent` — ISOSTS
|
|
51
|
+
- **`ruby` deleted** from `StyledContent` — ISOSTS's `styled-content` content
|
|
52
|
+
model omits `<ruby>` (NISO permits it transitively via the emphasis group).
|
|
52
53
|
Behaviour change: `<ruby>` in `<styled-content>` no longer round-trips.
|
|
53
54
|
- **13 element classes** modelled from ISOSTS.xsd: `Year`, `PubDate`,
|
|
54
55
|
`ReleaseVersionId`, `IsProof`, `AltText`, `LongDesc`, `TexMath`, `PubId`,
|
|
@@ -114,6 +115,7 @@ reaches `TbxIsoTml`/MathML. Those are shared namespaces, outside this ADR.
|
|
|
114
115
|
## Verification
|
|
115
116
|
|
|
116
117
|
1. `grep -rho "Sts::NisoSts::" lib/sts/iso_sts/ | wc -l` → `20`
|
|
117
|
-
2. Every attribute on an IsoSts model traces to a line in
|
|
118
|
+
2. Every *non-`@id`* attribute on an IsoSts model traces to a line in
|
|
119
|
+
`ISOSTS.xsd`; `@id` follows the 86948b9 convention
|
|
118
120
|
3. Autoload registry 1:1 with the directory (112/112)
|
|
119
121
|
4. `bundle exec rspec` green; `bundle exec rubocop` clean
|
data/lib/sts/iso_sts/body.rb
CHANGED
|
@@ -5,6 +5,7 @@ module Sts
|
|
|
5
5
|
class Body < Lutaml::Model::Serializable
|
|
6
6
|
attribute :id, :string
|
|
7
7
|
attribute :content_type, :string
|
|
8
|
+
attribute :specific_use, :string
|
|
8
9
|
attribute :paragraph, ::Sts::IsoSts::Paragraph, collection: true
|
|
9
10
|
attribute :sec, ::Sts::IsoSts::Sec, collection: true
|
|
10
11
|
attribute :term_sec, ::Sts::IsoSts::TermSec, collection: true
|
|
@@ -31,6 +32,7 @@ module Sts
|
|
|
31
32
|
|
|
32
33
|
map_attribute "id", to: :id
|
|
33
34
|
map_attribute "content-type", to: :content_type
|
|
35
|
+
map_attribute "specific-use", to: :specific_use
|
|
34
36
|
|
|
35
37
|
map_element "p", to: :paragraph
|
|
36
38
|
map_element "sec", to: :sec
|
data/lib/sts/iso_sts/bold.rb
CHANGED
|
@@ -22,7 +22,7 @@ module Sts
|
|
|
22
22
|
attribute :sc, ::Sts::IsoSts::Sc, collection: true
|
|
23
23
|
attribute :strike, ::Sts::IsoSts::Strike, collection: true
|
|
24
24
|
attribute :underline, ::Sts::IsoSts::Underline, collection: true
|
|
25
|
-
attribute :fn, ::Sts::
|
|
25
|
+
attribute :fn, ::Sts::IsoSts::Fn, collection: true
|
|
26
26
|
|
|
27
27
|
xml do
|
|
28
28
|
element "bold"
|
|
@@ -4,6 +4,9 @@ module Sts
|
|
|
4
4
|
module IsoSts
|
|
5
5
|
class CopyrightHolder < Lutaml::Model::Serializable
|
|
6
6
|
attribute :id, :string
|
|
7
|
+
attribute :content_type, :string
|
|
8
|
+
attribute :specific_use, :string
|
|
9
|
+
attribute :xml_lang, :string
|
|
7
10
|
attribute :content, :string, collection: true
|
|
8
11
|
attribute :sub, ::Sts::IsoSts::Sub
|
|
9
12
|
attribute :sup, ::Sts::IsoSts::Sup
|
|
@@ -11,6 +14,9 @@ module Sts
|
|
|
11
14
|
xml do
|
|
12
15
|
element "copyright-holder"
|
|
13
16
|
map_attribute "id", to: :id
|
|
17
|
+
map_attribute "content-type", to: :content_type
|
|
18
|
+
map_attribute "specific-use", to: :specific_use
|
|
19
|
+
map_attribute "xml:lang", to: :xml_lang
|
|
14
20
|
mixed_content
|
|
15
21
|
|
|
16
22
|
map_content to: :content
|
|
@@ -4,6 +4,9 @@ module Sts
|
|
|
4
4
|
module IsoSts
|
|
5
5
|
class CopyrightStatement < Lutaml::Model::Serializable
|
|
6
6
|
attribute :id, :string
|
|
7
|
+
attribute :content_type, :string
|
|
8
|
+
attribute :specific_use, :string
|
|
9
|
+
attribute :xml_lang, :string
|
|
7
10
|
attribute :content, :string, collection: true
|
|
8
11
|
attribute :bold, ::Sts::IsoSts::Bold
|
|
9
12
|
attribute :italic, ::Sts::IsoSts::Italic
|
|
@@ -13,6 +16,9 @@ module Sts
|
|
|
13
16
|
xml do
|
|
14
17
|
element "copyright-statement"
|
|
15
18
|
map_attribute "id", to: :id
|
|
19
|
+
map_attribute "content-type", to: :content_type
|
|
20
|
+
map_attribute "specific-use", to: :specific_use
|
|
21
|
+
map_attribute "xml:lang", to: :xml_lang
|
|
16
22
|
mixed_content
|
|
17
23
|
|
|
18
24
|
map_content to: :content
|
|
@@ -4,12 +4,16 @@ module Sts
|
|
|
4
4
|
module IsoSts
|
|
5
5
|
class CopyrightYear < Lutaml::Model::Serializable
|
|
6
6
|
attribute :id, :string
|
|
7
|
+
attribute :content_type, :string
|
|
8
|
+
attribute :specific_use, :string
|
|
7
9
|
attribute :content, :string
|
|
8
10
|
|
|
9
11
|
xml do
|
|
10
12
|
element "copyright-year"
|
|
11
13
|
|
|
12
14
|
map_attribute "id", to: :id
|
|
15
|
+
map_attribute "content-type", to: :content_type
|
|
16
|
+
map_attribute "specific-use", to: :specific_use
|
|
13
17
|
|
|
14
18
|
map_content to: :content
|
|
15
19
|
end
|
|
@@ -9,7 +9,7 @@ module Sts
|
|
|
9
9
|
attribute :xml_lang, :string
|
|
10
10
|
attribute :originator, :string
|
|
11
11
|
attribute :label, ::Sts::IsoSts::Label
|
|
12
|
-
attribute :math, Mml::
|
|
12
|
+
attribute :math, Mml::V2::Math
|
|
13
13
|
attribute :bold, ::Sts::IsoSts::Bold
|
|
14
14
|
attribute :italic, ::Sts::IsoSts::Italic
|
|
15
15
|
attribute :non_normative_note, ::Sts::IsoSts::NonNormativeNote
|
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
module Sts
|
|
4
4
|
module IsoSts
|
|
5
|
-
# ISOSTS declares <doc-number> as type="xs:string"
|
|
5
|
+
# ISOSTS declares <doc-number> as type="xs:string". The @id follows the
|
|
6
|
+
# NisoSts convention established in 86948b9, not ISOSTS itself.
|
|
6
7
|
class DocNumber < Lutaml::Model::Serializable
|
|
7
8
|
attribute :content, :string
|
|
9
|
+
attribute :id, :string
|
|
8
10
|
|
|
9
11
|
xml do
|
|
10
12
|
element "doc-number"
|
|
11
13
|
|
|
12
14
|
map_content to: :content
|
|
15
|
+
map_attribute "id", to: :id
|
|
13
16
|
end
|
|
14
17
|
end
|
|
15
18
|
end
|
data/lib/sts/iso_sts/doc_type.rb
CHANGED
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
module Sts
|
|
4
4
|
module IsoSts
|
|
5
|
-
# ISOSTS declares <doc-type> as type="xs:string"
|
|
5
|
+
# ISOSTS declares <doc-type> as type="xs:string". The @id follows the
|
|
6
|
+
# NisoSts convention established in 86948b9, not ISOSTS itself.
|
|
6
7
|
class DocType < Lutaml::Model::Serializable
|
|
7
8
|
attribute :content, :string
|
|
9
|
+
attribute :id, :string
|
|
8
10
|
|
|
9
11
|
xml do
|
|
10
12
|
element "doc-type"
|
|
11
13
|
|
|
12
14
|
map_content to: :content
|
|
15
|
+
map_attribute "id", to: :id
|
|
13
16
|
end
|
|
14
17
|
end
|
|
15
18
|
end
|
data/lib/sts/iso_sts/edition.rb
CHANGED
|
@@ -4,10 +4,16 @@ module Sts
|
|
|
4
4
|
module IsoSts
|
|
5
5
|
class Edition < Lutaml::Model::Serializable
|
|
6
6
|
attribute :id, :string
|
|
7
|
+
attribute :content_type, :string
|
|
8
|
+
attribute :specific_use, :string
|
|
9
|
+
attribute :xml_lang, :string
|
|
7
10
|
attribute :content, :string, collection: true
|
|
8
11
|
xml do
|
|
9
12
|
element "edition"
|
|
10
13
|
map_attribute "id", to: :id
|
|
14
|
+
map_attribute "content-type", to: :content_type
|
|
15
|
+
map_attribute "specific-use", to: :specific_use
|
|
16
|
+
map_attribute "xml:lang", to: :xml_lang
|
|
11
17
|
mixed_content
|
|
12
18
|
|
|
13
19
|
map_content to: :content
|