sts 0.6.8 → 0.6.9
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 +3 -0
- data/CLAUDE.md +99 -29
- data/README.adoc +49 -10
- data/lib/sts/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 55257a4c0bd11d4374ea655ffdef2d2a51c1e2fe8761cabbe450188065b85cb6
|
|
4
|
+
data.tar.gz: afe4c91a2e1b739eeffee4d044e8ea03b28774d43146aafdbd2d744d7577880a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: be6961ce1a6581c1fa6d7a51cb80253a99e01d53fabb31cb3d4feff43f8d87f7a2b283b3fbb8aa07ad31a91e4ac0a634e1bbbcbbf5dce733f45ad93bc77fdfc8
|
|
7
|
+
data.tar.gz: 9c476be12a1c7d51c9552892c2ad0bd677f16677e10587865d5a127ff20cf1be67b9e241a17e90155845ba704b58b404317cd1292bd138ddd00a182b875cb01e
|
data/.rubocop_todo.yml
CHANGED
|
@@ -24,6 +24,7 @@ Layout/LineLength:
|
|
|
24
24
|
- 'lib/sts/tbx_iso_tml/lang_set.rb'
|
|
25
25
|
- 'lib/sts/tbx_iso_tml/term_type.rb'
|
|
26
26
|
- 'spec/elements/new_elements_spec.rb'
|
|
27
|
+
- 'spec/iso_sts/schema_validation_spec.rb'
|
|
27
28
|
- 'spec/round_trip/reference_docs_spec.rb'
|
|
28
29
|
- 'spec/spec_helper.rb'
|
|
29
30
|
|
|
@@ -73,6 +74,7 @@ RSpec/DescribeClass:
|
|
|
73
74
|
- 'spec/fn_namespace_spec.rb'
|
|
74
75
|
- 'spec/mathml_version_spec.rb'
|
|
75
76
|
- 'spec/round_trip/reference_docs_spec.rb'
|
|
77
|
+
- 'spec/iso_sts/schema_validation_spec.rb'
|
|
76
78
|
|
|
77
79
|
# Offense count: 1
|
|
78
80
|
# This cop supports safe autocorrection (--autocorrect).
|
|
@@ -124,3 +126,4 @@ RSpec/SpecFilePathFormat:
|
|
|
124
126
|
- 'spec/sts_table_spec.rb'
|
|
125
127
|
- 'spec/iso_sts/iso_sts_spec.rb'
|
|
126
128
|
- 'spec/iso_sts/iso_sts_element_spec.rb'
|
|
129
|
+
- 'spec/iso_sts/schema_validation_spec.rb'
|
data/CLAUDE.md
CHANGED
|
@@ -1,58 +1,84 @@
|
|
|
1
1
|
# CLAUDE.md
|
|
2
2
|
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code)
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) for working with code in this repository.
|
|
4
4
|
|
|
5
5
|
## Build and Test Commands
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
# Run tests
|
|
8
|
+
# Run all tests + rubocop (default task)
|
|
9
|
+
bundle exec rake
|
|
10
|
+
|
|
11
|
+
# Run tests only
|
|
9
12
|
bundle exec rspec
|
|
10
13
|
|
|
11
|
-
# Run
|
|
12
|
-
bundle exec rspec spec/
|
|
14
|
+
# Run a specific spec file
|
|
15
|
+
bundle exec rspec spec/iso_sts/iso_sts_element_spec.rb
|
|
13
16
|
|
|
14
|
-
# Run
|
|
17
|
+
# Run rubocop
|
|
15
18
|
bundle exec rubocop
|
|
16
19
|
|
|
17
|
-
#
|
|
18
|
-
bundle exec
|
|
20
|
+
# Auto-fix linting offenses
|
|
21
|
+
bundle exec rubocop -a
|
|
19
22
|
```
|
|
20
23
|
|
|
21
24
|
## Architecture
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
sts-ruby is a Ruby gem for parsing and serialising NISO STS, ISOSTS, and
|
|
27
|
+
TBX-ISO-TML XML documents. It uses `lutaml-model` for declarative
|
|
28
|
+
serialisation.
|
|
24
29
|
|
|
25
|
-
### Namespace
|
|
30
|
+
### Namespace structure
|
|
26
31
|
|
|
27
32
|
```
|
|
28
33
|
Sts
|
|
29
|
-
├──
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
├──
|
|
33
|
-
├──
|
|
34
|
-
└──
|
|
34
|
+
├── IsoSts # ISOSTS v1.1 (frozen legacy, 2013 DTD)
|
|
35
|
+
├── NisoSts # NISO STS (evolving: 1.0, 1.2)
|
|
36
|
+
├── TbxIsoTml # TBX-ISO-TML (ISO 30042, shared)
|
|
37
|
+
├── Namespaces # XML namespace class declarations (TbxNamespace)
|
|
38
|
+
├── Profiles # ISO/IEC document profile validator
|
|
39
|
+
└── VERSION
|
|
35
40
|
```
|
|
36
41
|
|
|
37
|
-
###
|
|
42
|
+
### Architectural principle: namespace independence
|
|
43
|
+
|
|
44
|
+
ISOSTS and NISO STS are independent schemas that genuinely diverge.
|
|
45
|
+
Each `Sts::<Namespace>::<Class>` is modelled from its own schema source
|
|
46
|
+
(`reference-docs/isosts-v1/xsd/ISOSTS.xsd` for IsoSts,
|
|
47
|
+
`reference-docs/NISO-STS-extended-1-MathML3-XSD/` for NisoSts). NEVER:
|
|
48
|
+
|
|
49
|
+
- Alias `IsoSts::<X> = NisoSts::<X>` (couples the namespaces)
|
|
50
|
+
- Create a shared `Sts::Base::<X>` that both inherit from
|
|
51
|
+
- Reuse NisoSts types inside IsoSts or vice versa
|
|
52
|
+
|
|
53
|
+
TBX is shared (used by both IsoSts and NisoSts hosts), so cross-references
|
|
54
|
+
to `TbxIsoTml::*` are permitted — but each TbxIsoTml class must be a
|
|
55
|
+
true TBX-ISO-TML element, not a JATS/NISO STS element misplaced.
|
|
56
|
+
|
|
57
|
+
See `TODO.roadmap/00-overview.md` for the prioritised roadmap of remaining
|
|
58
|
+
work.
|
|
59
|
+
|
|
60
|
+
### MathML host binding
|
|
61
|
+
|
|
62
|
+
ISOSTS imports `ncbi-mathml2/mathml2.xsd` (MathML 2). NISO STS uses
|
|
63
|
+
MathML 3. TBX-ISO-TML is hosted under either. Bind per host:
|
|
38
64
|
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
65
|
+
- `IsoSts::*` math attributes → `Mml::V2::Math`
|
|
66
|
+
- `TbxIsoTml::*` math attributes → `Mml::V2::Math` (TBX-in-ISOSTS only)
|
|
67
|
+
- `NisoSts::*` math attributes → `Mml::V3::Math`
|
|
68
|
+
|
|
69
|
+
### Element class pattern
|
|
44
70
|
|
|
45
|
-
**Example element structure:**
|
|
46
71
|
```ruby
|
|
47
72
|
module Sts
|
|
48
|
-
module
|
|
73
|
+
module IsoSts
|
|
49
74
|
class SomeElement < Lutaml::Model::Serializable
|
|
50
75
|
attribute :id, :string
|
|
51
|
-
attribute :content, :string
|
|
52
|
-
attribute :child, ::Sts::
|
|
76
|
+
attribute :content, :string, collection: true
|
|
77
|
+
attribute :child, ::Sts::IsoSts::ChildElement, collection: true
|
|
53
78
|
|
|
54
79
|
xml do
|
|
55
80
|
element "some-element"
|
|
81
|
+
ordered # preserve child order on serialise
|
|
56
82
|
map_attribute "id", to: :id
|
|
57
83
|
map_content to: :content
|
|
58
84
|
map_element "child", to: :child
|
|
@@ -62,11 +88,55 @@ module Sts
|
|
|
62
88
|
end
|
|
63
89
|
```
|
|
64
90
|
|
|
65
|
-
|
|
91
|
+
### Autoload convention
|
|
92
|
+
|
|
93
|
+
`lib/sts.rb` autoloads top-level namespaces. `lib/sts/<namespace>.rb`
|
|
94
|
+
autoloads every class in that namespace, organised by category with
|
|
95
|
+
leading comments and alphabetical order within each group.
|
|
96
|
+
|
|
97
|
+
External gems are eager-required at the top of `lib/sts.rb`
|
|
98
|
+
(`require "lutaml/model"`, `require "mml"`). Internal code never uses
|
|
99
|
+
`require_relative` or `require` with internal paths — autoload only.
|
|
100
|
+
Enforced by `spec/anti_patterns_spec.rb`.
|
|
101
|
+
|
|
102
|
+
### Anti-patterns (forbidden; enforced by spec)
|
|
103
|
+
|
|
104
|
+
`spec/anti_patterns_spec.rb` runs 9 per-file checks on every `lib/` file:
|
|
105
|
+
|
|
106
|
+
- `method_missing`, `respond_to_missing?` — forbidden (hides interfaces)
|
|
107
|
+
- `Object.const_get` — forbidden (runtime string lookup)
|
|
108
|
+
- `.send(` — forbidden (bypasses access control)
|
|
109
|
+
- `instance_variable_set` / `instance_variable_get` — forbidden (breaks encapsulation)
|
|
110
|
+
- `respond_to?` type-checks — forbidden (use `is_a?` or redesign so the check isn't needed)
|
|
111
|
+
- Hand-rolled serialization methods on `Serializable` subclasses:
|
|
112
|
+
`to_h`, `to_hash`, `from_h`, `from_hash`, `to_json`, `from_json`,
|
|
113
|
+
`serialize`, `deserialize`, `to_xml`, `from_xml` — forbidden
|
|
114
|
+
(use `attribute` + `mapping`; framework-generated serialisation is correct)
|
|
115
|
+
- `require_relative` in lib/ — forbidden (use autoload)
|
|
116
|
+
- `require` with internal library path — forbidden (use autoload;
|
|
117
|
+
external gems like `lutaml/model` are allowlisted)
|
|
118
|
+
|
|
119
|
+
### Schema authority
|
|
120
|
+
|
|
121
|
+
For any new IsoSts element, generate the attribute list from
|
|
122
|
+
`reference-docs/isosts-v1/xsd/ISOSTS.xsd` directly. Don't copy from
|
|
123
|
+
NisoSts — the schemas disagree on most elements. Attribute-list
|
|
124
|
+
specifications ("X models its configured attribute set") are the
|
|
125
|
+
project's defence against drift, since round-tripping alone cannot prove
|
|
126
|
+
schema conformance.
|
|
127
|
+
|
|
128
|
+
### Spec patterns
|
|
66
129
|
|
|
67
|
-
**
|
|
130
|
+
- **Attribute-set assertions** — `expect(Foo.attributes.keys).to match_array(%i[id content_type ...])`
|
|
131
|
+
- **Child-type assertions** — `expect(Bar.attributes[:foo].type).to eq(Baz)`
|
|
132
|
+
- **Round-trip tests** — `expect(Foo.to_xml(Foo.from_xml(xml))).to be_xml_equivalent_to(xml)`
|
|
133
|
+
- **Schema-validation tests** — `spec/schema_validation_spec.rb` validates
|
|
134
|
+
IsoSts output against ISOSTS.xsd directly via Nokogiri::XML::Schema
|
|
68
135
|
|
|
69
|
-
### Reference
|
|
136
|
+
### Reference data
|
|
70
137
|
|
|
71
|
-
- XSD
|
|
138
|
+
- ISOSTS XSD: `reference-docs/isosts-v1/xsd/ISOSTS.xsd`
|
|
139
|
+
- NISO STS XSD: `reference-docs/NISO-STS-extended-1-MathML3-XSD/`
|
|
140
|
+
- TBX schema (under ISOSTS): `reference-docs/isosts-v1/xsd/tbx.xsd`
|
|
72
141
|
- Test fixtures: `spec/fixtures/`
|
|
142
|
+
- TODO roadmap: `TODO.roadmap/`
|
data/README.adoc
CHANGED
|
@@ -140,23 +140,26 @@ sts.class.name # => "Sts::IsoSts::Standard"
|
|
|
140
140
|
|
|
141
141
|
==== ISOSTS MathML 2
|
|
142
142
|
|
|
143
|
-
ISOSTS uses MathML 2 (not MathML 3
|
|
143
|
+
ISOSTS uses MathML 2 (not MathML 3 like NISO STS). All MathML is provided
|
|
144
|
+
by the mml gem, bound per host:
|
|
145
|
+
|
|
146
|
+
* `IsoSts::*` math attributes → `Mml::V2::Math`
|
|
147
|
+
* `TbxIsoTml::*` math attributes → `Mml::V2::Math` (TBX-in-ISOSTS only)
|
|
148
|
+
* `NisoSts::*` math attributes → `Mml::V3::Math`
|
|
144
149
|
|
|
145
150
|
[source,ruby]
|
|
146
151
|
----
|
|
147
|
-
# Access MathML 2 content
|
|
148
152
|
disp_formula = sts.body.sec.first.disp_formula
|
|
149
|
-
math = disp_formula.math # =>
|
|
150
|
-
|
|
151
|
-
# MathML 2 elements
|
|
152
|
-
math.id # => "mml_1"
|
|
153
|
-
math.display # => "block" or "inline"
|
|
153
|
+
math = disp_formula.math # => Mml::V2::Math
|
|
154
154
|
|
|
155
|
-
#
|
|
156
|
-
|
|
155
|
+
# Round-trip preserves mml: prefix
|
|
156
|
+
disp_formula.to_xml # => <disp-formula><mml:math ...>...</mml:math></disp-formula>
|
|
157
157
|
----
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
MathML 2 and 3 share the same XML namespace (`http://www.w3.org/1998/Math/MathML`),
|
|
160
|
+
so `Mml::Namespace` (the mml gem's top-level namespace class) is used
|
|
161
|
+
directly in both `IsoSts::Standard#namespace_scope` and
|
|
162
|
+
`NisoSts::Standard#namespace_scope`.
|
|
160
163
|
|
|
161
164
|
==== ISOSTS TBX Terminology
|
|
162
165
|
|
|
@@ -191,6 +194,42 @@ sts = Sts::NisoSts::Standard.from_xml(xml_with_tbx)
|
|
|
191
194
|
sts = Sts::IsoSts::Standard.from_xml(xml_with_tbx)
|
|
192
195
|
----
|
|
193
196
|
|
|
197
|
+
== Architecture principles
|
|
198
|
+
|
|
199
|
+
=== Namespace independence
|
|
200
|
+
|
|
201
|
+
`IsoSts`, `NisoSts`, and `TbxIsoTml` are independent schemas that
|
|
202
|
+
genuinely diverge. Each `Sts::<Namespace>::<Class>` is modelled from its
|
|
203
|
+
own schema source — never aliased across namespaces, never sharing base
|
|
204
|
+
classes. The schemas disagree on most elements (e.g., `IsoSts::Fig` has
|
|
205
|
+
`title`/`alternatives` that `NisoSts::Figure` lacks), so sharing types
|
|
206
|
+
would fight the schemas and violate the Open/Closed principle.
|
|
207
|
+
|
|
208
|
+
=== Anti-pattern enforcement
|
|
209
|
+
|
|
210
|
+
`spec/anti_patterns_spec.rb` runs 9 per-file checks across `lib/` to
|
|
211
|
+
forbid: `method_missing`, `respond_to_missing?`, `Object.const_get`,
|
|
212
|
+
`.send(`, `instance_variable_set`/`get`, `respond_to?` type-checks,
|
|
213
|
+
hand-rolled serialization methods on `Serializable` subclasses
|
|
214
|
+
(`to_h`, `to_xml`, `from_xml`, etc.), `require_relative`, and
|
|
215
|
+
internal `require`. See `CLAUDE.md` for the rationale.
|
|
216
|
+
|
|
217
|
+
=== Schema validation
|
|
218
|
+
|
|
219
|
+
`spec/schema_validation_spec.rb` validates IsoSts output against the
|
|
220
|
+
canonical `reference-docs/isosts-v1/xsd/ISOSTS.xsd` via
|
|
221
|
+
`Nokogiri::XML::Schema`. Round-tripping alone cannot prove schema
|
|
222
|
+
conformance (a model that invents or drops an attribute still
|
|
223
|
+
round-trips symmetrically); the XSD is the only authoritative check.
|
|
224
|
+
|
|
225
|
+
=== Autoload convention
|
|
226
|
+
|
|
227
|
+
`lib/sts.rb` autoloads top-level namespaces. Each namespace's
|
|
228
|
+
`lib/sts/<namespace>.rb` autoloads every class in alphabetical order
|
|
229
|
+
within category groups. External gems (`lutaml/model`, `mml`) are
|
|
230
|
+
eager-required at the top of `lib/sts.rb`; internal code uses autoload
|
|
231
|
+
only — no `require_relative`, no `require "sts/..."`.
|
|
232
|
+
|
|
194
233
|
== Credits
|
|
195
234
|
|
|
196
235
|
This gem is developed, maintained and funded by
|
data/lib/sts/version.rb
CHANGED