glossarist 2.6.5 → 2.6.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e3cd8f02f83acf4b2c43139fe2ec0afd8b635860e02e31e530827297648168b
4
- data.tar.gz: 755e65d489c0d889ae3d9f4652703d55055aa0b0f0b669b588380070746fc63a
3
+ metadata.gz: d0e6019628f010211b1f05fbc2297a9c20b53b85ac23e57ac71d8d09ac933dcc
4
+ data.tar.gz: 65bc93a2714354d47261e21d6ee34c0b46f6d967688188c2af04dcf04ed3aaca
5
5
  SHA512:
6
- metadata.gz: 5794f170646fa14bae1f7e9d3bf82499c4298f3976804d6cf1b0d33dea90cd26715c5c394cfd6335f8616c4a55d05d78b9cdeb0f653b7a86d629a7b3d0bfe799
7
- data.tar.gz: 7681ef4afc518c7cf5bc4fe99a62dc3b41a44c66778257fc5f1e81004867ed86b98ef4c9e4026b8c5a11791d3d618849cf4bf809f11e07d4d87dfef56ffbec5c
6
+ metadata.gz: 86d9478fdc0bdecdfdce06dd607bd6254c04a9be4e261f41131571c60c043af5b84a2dbef7904c721e0c2646c9436fc734038c4ccd5da3a7a8c31b3fb6fc5429
7
+ data.tar.gz: 0d9c205d5733dcc767f2f1922eb43fcfdc8e2b445f7c144667bdb508cc285a24e2b50fef9326d085642f1269177f0044401d92fb2128d22466afb91ef25faa34
@@ -1,11 +1,8 @@
1
- # Auto-generated by Cimas: Do not edit it manually!
2
- # See https://github.com/metanorma/cimas
3
1
  name: release
4
2
 
5
3
  permissions:
6
4
  contents: write
7
5
  id-token: write
8
- pull-requests: write
9
6
 
10
7
  on:
11
8
  workflow_dispatch:
@@ -21,7 +18,7 @@ on:
21
18
 
22
19
  jobs:
23
20
  release:
24
- uses: relaton/support/.github/workflows/release.yml@main
21
+ uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
25
22
  with:
26
23
  next_version: ${{ github.event.inputs.next_version }}
27
24
  secrets:
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-05-12 10:41:50 UTC using RuboCop version 1.86.1.
3
+ # on 2026-05-13 07:45:58 UTC using RuboCop version 1.86.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -11,13 +11,64 @@ Gemspec/RequiredRubyVersion:
11
11
  Exclude:
12
12
  - 'glossarist.gemspec'
13
13
 
14
- # Offense count: 254
14
+ # Offense count: 3
15
+ # This cop supports safe autocorrection (--autocorrect).
16
+ # Configuration parameters: EnforcedStyle, IndentationWidth.
17
+ # SupportedStyles: with_first_argument, with_fixed_indentation
18
+ Layout/ArgumentAlignment:
19
+ Exclude:
20
+ - 'lib/glossarist/designation/expression.rb'
21
+ - 'spec/unit/designations_spec.rb'
22
+
23
+ # Offense count: 1
24
+ # This cop supports safe autocorrection (--autocorrect).
25
+ # Configuration parameters: EnforcedStyleAlignWith.
26
+ # SupportedStylesAlignWith: either, start_of_block, start_of_line
27
+ Layout/BlockAlignment:
28
+ Exclude:
29
+ - 'spec/unit/designations_spec.rb'
30
+
31
+ # Offense count: 1
32
+ # This cop supports safe autocorrection (--autocorrect).
33
+ Layout/BlockEndNewline:
34
+ Exclude:
35
+ - 'spec/unit/designations_spec.rb'
36
+
37
+ # Offense count: 7
38
+ # This cop supports safe autocorrection (--autocorrect).
39
+ # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
40
+ # SupportedHashRocketStyles: key, separator, table
41
+ # SupportedColonStyles: key, separator, table
42
+ # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
43
+ Layout/HashAlignment:
44
+ Exclude:
45
+ - 'spec/unit/concept_data_spec.rb'
46
+ - 'spec/unit/designations_spec.rb'
47
+
48
+ # Offense count: 2
49
+ # This cop supports safe autocorrection (--autocorrect).
50
+ # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
51
+ # SupportedStylesAlignWith: start_of_line, relative_to_receiver
52
+ Layout/IndentationWidth:
53
+ Exclude:
54
+ - 'spec/unit/designations_spec.rb'
55
+
56
+ # Offense count: 267
15
57
  # This cop supports safe autocorrection (--autocorrect).
16
58
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
17
59
  # URISchemes: http, https
18
60
  Layout/LineLength:
19
61
  Enabled: false
20
62
 
63
+ # Offense count: 7
64
+ # This cop supports safe autocorrection (--autocorrect).
65
+ # Configuration parameters: AllowInHeredoc.
66
+ Layout/TrailingWhitespace:
67
+ Exclude:
68
+ - 'lib/glossarist/designation/expression.rb'
69
+ - 'spec/unit/concept_data_spec.rb'
70
+ - 'spec/unit/designations_spec.rb'
71
+
21
72
  # Offense count: 1
22
73
  # Configuration parameters: AllowedMethods.
23
74
  # AllowedMethods: enums
data/CLAUDE.md CHANGED
@@ -23,8 +23,23 @@ All model classes use `Lutaml::Model::Serializable` for serialization.
23
23
  - **`ManagedConcept`** (`managed_concept.rb`) — a managed concept with `ManagedConceptData` (groups, localized_concepts map, sources), related concepts, dates, and status. Delegates localization via `add_l10n`/`localization(lang)`.
24
24
  - **`Concept`** (`concept.rb`) — base concept with `ConceptData` (definition, terms/designations, notes, examples, sources, dates, language_code). Parent of `LocalizedConcept`.
25
25
  - **`LocalizedConcept`** (`localized_concept.rb`) — extends `Concept` with `classification`, `entry_status`, `review_type`.
26
- - **`ConceptData`** (`concept_data.rb`) — the data payload inside `Concept`: definition, terms, examples, notes, sources, language_code. Uses `DetailedDefinition` collections for definition/examples/notes.
27
- - **`ManagedConceptData`** (`managed_concept_data.rb`) — the data payload inside `ManagedConcept`: id, localized_concepts hash (lang_code => uuid), groups, sources.
26
+ - **`ConceptData`** (`concept_data.rb`) — the data payload inside `Concept`: definition, terms, examples, notes, sources, non_verb_rep (collection of `NonVerbRep` resource references), language_code (ISO 639), script (ISO 15924), system (ISO 24229 conversion system code). Uses `DetailedDefinition` collections for definition/examples/notes.
27
+ - **`ManagedConceptData`** (`managed_concept_data.rb`) — the data payload inside `ManagedConcept`: id, localized_concepts hash (lang_code => uuid), domains (ConceptReference collection — upper concept references replacing the old `groups` string array), sources.
28
+
29
+ ### NonVerbRep (Resource Reference)
30
+
31
+ `NonVerbRep` (`non_verb_rep.rb`) models non-verbal representations as URI references to external resources (images, tables, formulas), not embedded content. Attributes: `type` (image/table/formula), `ref` (URI — relative path, URN, or URL), `text` (alt text), `sources` (ConceptSource collection).
32
+
33
+ ### ConceptReference & RelatedConcept
34
+
35
+ - **`ConceptReference`** (`concept_reference.rb`) — a typed reference to another concept. Local refs use `concept_id` alone; external refs use `source` (URN prefix) + `concept_id` or a direct `urn` field. Has `local?`/`external?` predicates. No `to_gcr_hash` or `from_urn` — model-driven architecture uses lutaml-model for serialization; URN construction/parsing belongs in `UrnResolver`.
36
+ - **`RelatedConcept`** (`related_concept.rb`) — a concept with a typed relationship. Relationship types cover ISO 10241-1 (deprecates/supersedes/superseded_by/compare/contrast/see), ISO 25964/SKOS (broader/narrower/broader_generic/narrower_generic/broader_partitive/narrower_partitive/broader_instantial/narrower_instantial/equivalent/close_match/broad_match/narrow_match/related_match), ISO 12620/TBX (homograph/false_friend/related_concept/related_concept_broader/related_concept_narrower/sequentially_related_concept/spatially_related_concept/temporally_related_concept), and designation-level (abbreviated_form_for/short_form_for). Types are defined in `config.yml` under `related_concept.type`.
37
+
38
+ ### Reference Resolution
39
+
40
+ - **`ReferenceExtractor`** (`reference_extractor.rb`) — extracts `ConceptReference` and `AssetReference` objects from `{{...}}` mentions and `image::...[]` references in concept text fields.
41
+ - **`ReferenceResolver`** (`reference_resolver.rb`) — resolves references via adapter chain (local → package → remote). Supports route overrides for URI remapping.
42
+ - **`UrnResolver`** (`urn_resolver.rb`) — converts URNs to canonical HTTP URLs (IEC Electropedia, ISO OBP). Extensible via `register_scheme`. All URN construction/parsing logic lives here, not in the model.
28
43
 
29
44
  ### UUID Generation
30
45
 
@@ -34,6 +49,16 @@ Concepts use deterministic UUID v5 (SHA-1) derived from their serialized YAML co
34
49
 
35
50
  `Designation::Base` (`designation/base.rb`) uses a self-referencing factory pattern (`of_yaml`) that dispatches to subclasses based on `type` field: `Expression`, `Symbol`, `Abbreviation`, `GraphicalSymbol`, `LetterSymbol`. The bi-directional mapping is in `SERIALIZED_TYPES` (`designation.rb`).
36
51
 
52
+ Designation inheritance hierarchy (MECE):
53
+ - **Base** — `designation`, `normative_status` (preferred/admitted/deprecated/superseded), `geographical_area`, `type`, `language`/ISO 639, `script`/ISO 15924, `system`/ISO 24229, `international`, `absent`, `pronunciation` (collection of `Pronunciation` objects), `sources` (collection of `ConceptSource` — per-designation sources per ISO 10241-1 §6.8), `term_type` (ISO 12620 term type classification — 24 values from `config.yml`), `related` (collection of `RelatedConcept` — designation-level intra-entry relationships: `abbreviated_form_for`, `short_form_for`)
54
+ - **Expression < Base** — `prefix`, `usage_info`, `field_of_application` (IEC "specific use"), `grammar_info`
55
+ - **Abbreviation < Expression** — abbreviation type booleans (`acronym`, `initialism`, `truncation`) from `config.yml`
56
+ - **Symbol < Base** — (no additional attributes)
57
+ - **LetterSymbol < Symbol** — `text`
58
+ - **GraphicalSymbol < Symbol** — `text`, `image`
59
+
60
+ `ConceptData#domain` stores URI references (relative like `section-103-01`, URN like `urn:iec:std:iec:60050-103-01`, or URL like `https://...`) to subject area concepts.
61
+
37
62
  ### YAML Serialization
38
63
 
39
64
  - **`ConceptManager`** (`concept_manager.rb`) — handles file I/O. Supports two storage formats:
data/README.adoc CHANGED
@@ -101,7 +101,7 @@ related:: Array of <<related-concept,RelatedConcept>>
101
101
  status:: Enum for the normative status of the term.
102
102
  dates:: Array of <<concept-date,ConceptDate>>
103
103
  localized_concepts:: Hash of all localizations where keys are language codes and values are uuid of the localized concept.
104
- groups:: Array of groups in string format
104
+ domains:: Array of <<concept-reference,ConceptReference>> upper concepts (subject areas, concept schemes, organizing concepts) that this concept belongs to across all languages. Each domain is a typed reference (e.g. `{ concept_id: "103", ref_type: "domain" }`).
105
105
  localizations:: Hash of all localizations for this concept where keys are language codes and values are instances of <<localized-concept,LocalizedConcept>>.
106
106
 
107
107
  There are two ways to initialize and populate a managed concept
@@ -118,9 +118,8 @@ concept = Glossarist::ManagedConcept.new({
118
118
  "eng" => "<uuid>"
119
119
  },
120
120
  "localizations" => <Array of localized concepts or localized concept hashes>,
121
- "groups" => [
122
- "foo",
123
- "bar",
121
+ "domains" => [
122
+ { "concept_id" => "103", "ref_type" => "domain" },
124
123
  ],
125
124
  },
126
125
  })
@@ -132,7 +131,9 @@ concept = Glossarist::ManagedConcept.new({
132
131
  ----
133
132
  concept = Glossarist::ManagedConcept.new
134
133
  concept.id = "123"
135
- concept.groups = ["foo", "bar"]
134
+ concept.data.domains = [
135
+ Glossarist::ConceptReference.new(concept_id: "103", ref_type: "domain"),
136
+ ]
136
137
  concept.localizations = <Array of localized concepts or localized concept hashes>
137
138
  ----
138
139
 
@@ -146,55 +147,252 @@ Localized concept has the following fields
146
147
  id:: An optional identifier for the term, to be used in cross-references.
147
148
  uuid:: UUID for the concept
148
149
  designations:: Array of <<designation,Designations>> under which the term being defined is known. This method will also accept an array of hashes for designation and will convert them to their respective classes.
149
- domain:: An optional semantic domain for the term being defined, in case the term is ambiguous between several semantic domains.
150
+ domain:: URI reference to the subject area or section concept. Can be a relative URI (e.g. `section-103-01`), a URN (e.g. `urn:iec:std:iec:60050-103-01`), or a URL (e.g. `https://www.electropedia.org/iev/iev.nsf/display?openform&ievref=103-01`). This is the per-language upper concept reference — the subject area for this specific localization. Different languages may assign the same abstract concept to different domains.
151
+ related:: Array of <<related-concept,RelatedConcept>> — per-language concept relationships. Concept hierarchies can differ across languages (e.g. Russian distinguishes голубой/siniy as coordinate basic colors, while English unifies them under "blue"). Language-specific broader/narrower/equivalent relationships go here.
150
152
  subject:: Subject of the term.
151
153
  definition:: Array of <<detailed-definition,Detailed Definition>> of the term.
152
154
  non_verb_rep:: Array of <<non-verbal,non-verbal>> representations used to help define the term.
153
155
  notes:: Zero or more notes about the term. A note is in <<detailed-definition,Detailed Definition>> format.
154
156
  examples:: Zero or more examples of how the term is to be used in <<detailed-definition,Detailed Definition>> format.
155
157
  language_code:: The language of the localization, as an ISO-639 3-letter code.
158
+ script:: The script of the localization, as an ISO 15924 4-letter code (e.g. `Hans` for Simplified Chinese, `Latn` for Latin, `Cyrl` for Cyrillic). Optional — when omitted, the default script for the language is assumed.
159
+ system:: The ISO 24229 conversion system code used to produce this localization (e.g. `Var:jpn-Hrkt:Latn:Hepburn-1886` for Hepburn-romanized Japanese). Optional — only set when the localization is a romanization or transliteration.
156
160
  entry_status:: Entry status of the concept. Must be one of the following: +notValid+, +valid+, +superseded+, +retired+.
157
161
  classification:: Classification of the concept. Must be one of the following: +preferred+, +admitted+, +deprecated+.
158
162
 
159
163
  [[id,designation]]
160
- === Designation::Base
164
+ === Designation
165
+
166
+ A name under which a managed term is known. Designations follow an
167
+ inheritance hierarchy based on ISO 10241-1 and the Metanorma concept model.
168
+
169
+ ==== Designation::Base (common to all types)
170
+
171
+ designation:: String — the term text or symbol.
172
+ normative_status:: Enum — one of `preferred`, `admitted`, `deprecated`, `superseded`.
173
+ geographical_area:: String — geographic usage region (ISO 3166-1 country code).
174
+ language:: String — language of this designation (ISO 639 code). Usually inherited from the LocalizedConcept's `language_code`, but can differ for borrowed terms.
175
+ script:: String — script of the designation text (ISO 15924 code, e.g. `Hani` for Kanji, `Latn` for Latin, `Cyrl` for Cyrillic).
176
+ system:: String — ISO 24229 conversion system code used to produce this designation (e.g. `Var:jpn-Hrkt:Latn:Hepburn-1886` for Hepburn romanization). Optional — only set when the designation is a romanization or transliteration.
177
+ international:: Boolean — whether the designation is used internationally.
178
+ absent:: Boolean — whether the designation is intentionally absent in this language.
179
+ pronunciation:: Collection of `Pronunciation` entries — phonetic or romanized representations of the designation.
180
+ sources:: Collection of `ConceptSource` entries — bibliographic sources for this designation (ISO 10241-1 §6.8).
181
+ term_type:: Enum (ISO 12620) — optional classification of the designation's term type. See <<iso12620-term-types>> below.
182
+ related:: Collection of `RelatedConcept` entries — term-level (designation-to-designation) relationships within the same concept entry. Used for linking abbreviated forms to full forms, short forms to expanded forms, etc. (TBX xref types).
183
+ +
184
+ Each `Pronunciation` entry has:
185
+ +
186
+ [cols="1,1,2"]
187
+ |===
188
+ |Attribute |Standard |Description
189
+
190
+ |`content` |— |The pronunciation text
191
+ |`language` |ISO 639 |Language/dialect being pronounced (3-letter code)
192
+ |`script` |ISO 15924 |Script of the pronunciation text (4-letter code)
193
+ |`country` |ISO 3166-1 |Country variant (2-letter code, optional)
194
+ |`system` |ISO 24229 |Conversion system code or identifier (e.g. `IPA`, `Var:jpn-Hrkt:Latn:Hepburn-1886`)
195
+ |===
196
+ +
197
+ Example:
198
+ +
199
+ [,yaml]
200
+ ----
201
+ pronunciation:
202
+ - content: "toːkjoː"
203
+ language: jpn
204
+ script: Latn
205
+ system: IPA
206
+ - content: "Tōkyō"
207
+ language: jpn
208
+ script: Latn
209
+ system: "Var:jpn-Hrkt:Latn:Hepburn-1886"
210
+ ----
211
+
212
+ ==== Designation::Expression (text-based, inherits Base)
161
213
 
162
- A name under which a managed term is known.
214
+ prefix:: String text before the designation.
215
+ usage_info:: String — disambiguation text for the designation.
216
+ field_of_application:: String — IEC "specific use", appears in angle brackets after the designation (e.g. "in communication theory").
217
+ grammar_info:: Array of GrammarInfo — gender, number, part of speech.
163
218
 
164
- Methods::
165
- `from_h(options)`::: Creates a new designation instance based on the specified type.
219
+ ==== Designation::Abbreviation (inherits Expression)
220
+
221
+ acronym:: Boolean — is this an acronym?
222
+ initialism:: Boolean — is this an initialism?
223
+ truncation:: Boolean — is this a truncation?
224
+
225
+ ==== Designation::Symbol (inherits Base)
226
+
227
+ No additional attributes beyond Base.
228
+
229
+ ==== Designation::LetterSymbol (inherits Symbol)
230
+
231
+ text:: String — the letter symbol text.
232
+
233
+ ==== Designation::GraphicalSymbol (inherits Symbol)
234
+
235
+ text:: String — description of the symbol.
236
+ image:: String — the graphical symbol (emoji, path, or data URL).
237
+
238
+ ==== Factory Method
239
+
240
+ `Designation::Base.from_h(options)` creates a new designation instance based on the specified type.
166
241
 
167
242
  Parameters::
168
243
  * options (Hash) - The options for creating the designation.
169
- * "type" (String) - The type of designation (expression, symbol, abbreviation, graphical_symbol, letter_symbol). Note: type key should be string and not a symbol so { type: "expression" } will not work.
244
+ * "type" (String) - The type of designation (`expression`, `symbol`, `abbreviation`, `graphical_symbol`, `letter_symbol`). Note: type key should be string and not a symbol so `{ type: "expression" }` will not work.
170
245
  * Additional options depend on the specific designation type.
171
246
 
172
247
  Returns::
173
- Designation::{type}::: A new instance of specified type. e.g `Glossarist::Designation::Base.from_h("type" => "expression")` will return `Glossarist::Designation::Expression`
248
+ Designation::{type}::: A new instance of specified type.
174
249
 
175
250
  Example
176
251
  [,ruby]
177
252
  ----
178
- # Example usage of Designation::Base class
253
+ # Expression with field of application
254
+ expr = Designation::Base.from_h({
255
+ "type" => "expression",
256
+ "designation" => "information",
257
+ "normative_status" => "preferred",
258
+ "field_of_application" => "in communication theory",
259
+ })
260
+
261
+ # International abbreviation
262
+ abbr = Designation::Base.from_h({
263
+ "type" => "abbreviation",
264
+ "designation" => "ISO",
265
+ "international" => true,
266
+ "acronym" => true,
267
+ })
268
+ ----
269
+
270
+ [[iso12620-term-types]]
271
+ ==== ISO 12620 Term Types
272
+
273
+ The `term_type` attribute on `Designation::Base` classifies designations
274
+ according to ISO 12620 (also used as TBX `termType`). This is orthogonal to
275
+ the structural designation `type` (expression/abbreviation/symbol): the
276
+ structural type determines how the designation is serialized, while
277
+ `term_type` provides ISO 12620 semantic classification.
278
+
279
+ [cols="1,2"]
280
+ |===
281
+ |Term type |Description
282
+
283
+ |`abbreviation`
284
+ |A shortened form of a word or phrase (general category)
285
+
286
+ |`acronym`
287
+ |An abbreviation pronounced as a word (e.g. NATO, laser)
288
+
289
+ |`clipped_term`
290
+ |A term formed by clipping part of a longer term (e.g. "phone" from "telephone")
291
+
292
+ |`common_name`
293
+ |A name in common use for a concept (e.g. "water" vs H₂O)
294
+
295
+ |`entry_term`
296
+ |The headword or main term in a terminological entry
297
+
298
+ |`equation`
299
+ |A mathematical equation used as a designation
300
+
301
+ |`formula`
302
+ |A chemical or mathematical formula (e.g. H₂O, E=mc²)
303
+
304
+ |`full_form`
305
+ |The complete, unabbreviated form of a designation (e.g. "World Wide Web")
306
+
307
+ |`initialism`
308
+ |An abbreviation pronounced letter by letter (e.g. "URL", "FBI")
309
+
310
+ |`internationalism`
311
+ |A term used with the same meaning across many languages (e.g. "computer", "algorithm")
312
+
313
+ |`international_scientific_term`
314
+ |A term established by international scientific agreement (e.g. "hydrogen")
315
+
316
+ |`logical_expression`
317
+ |A logical or Boolean expression used as a designation
318
+
319
+ |`part_number`
320
+ |A part number or catalog identifier used as a designation
179
321
 
180
- attributes_for_expression = { designation: "foobar", geographical_area: "abc", normative_status: "status" }
181
- designation_expression = Designation::Base.from_h({ "type" => "expression" }.merge(attributes_for_expression))
322
+ |`phraseological_unit`
323
+ |A multi-word expression or phrase functioning as a term (e.g. "software engineering")
182
324
 
183
- attributes_for_abbreviation = { designation: "foobar", geographical_area: "abc", normative_status: "status", international: true }
184
- designation_abbreviation = Designation::Base.from_h({ "type" => "abbreviation" }.merge(attributes_for_abbreviation))
325
+ |`transcribed_form`
326
+ |A designation produced by phonetic transcription from another script
185
327
 
328
+ |`transliterated_form`
329
+ |A designation produced by transliteration from another script (e.g. "Moskva" from "Москва")
330
+
331
+ |`short_form`
332
+ |A shortened form of a designation that is not an abbreviation (e.g. "US" for "United States")
333
+
334
+ |`shortcut`
335
+ |A keyboard shortcut or command sequence (e.g. "Ctrl+V" for paste)
336
+
337
+ |`sku`
338
+ |A stock keeping unit identifier
339
+
340
+ |`standard_text`
341
+ |A standardized text passage used as a designation
342
+
343
+ |`symbol`
344
+ |A non-verbal symbol representing the concept (e.g. Ω for ohm)
345
+
346
+ |`synonym`
347
+ |A term with the same meaning in the same language, used as an alternative designation
348
+
349
+ |`synonymous_phrase`
350
+ |A phrase that is synonymous with the preferred designation
351
+
352
+ |`variant`
353
+ |A spelling, regional, or stylistic variant of another designation
354
+ |===
355
+
356
+ ==== Designation-Level Relationships (TBX xref)
357
+
358
+ Designations can have intra-entry relationships — links between
359
+ designations of the *same* concept. These correspond to TBX `xref`
360
+ elements on term information groups (`<tig>`).
361
+
362
+ [cols="1,2"]
363
+ |===
364
+ |Relationship type |Description
365
+
366
+ |`abbreviated_form_for`
367
+ |This designation is an abbreviated form of the target (e.g. "WWW" → "World Wide Web")
368
+
369
+ |`short_form_for`
370
+ |This designation is a short form of the target (e.g. "US" → "United States of America")
371
+ |===
372
+
373
+ Example:
374
+ [,yaml]
375
+ ----
376
+ terms:
377
+ - designation: WWW
378
+ type: abbreviation
379
+ term_type: acronym
380
+ related:
381
+ - type: abbreviated_form_for
382
+ content: "World Wide Web"
383
+ - designation: World Wide Web
384
+ type: expression
385
+ term_type: full_form
186
386
  ----
187
387
 
188
388
  [[id,related-concept]]
189
389
  === RelatedConcept
190
390
 
191
- A term related to the current term.
192
-
193
- Following fields are available for the Related Concept
391
+ A concept related to the current concept with a typed relationship.
194
392
 
195
- type:: An enum to denote the relation of the term to the current term.
196
- content:: The designation of the related term.
197
- ref:: A <<citation, citation>> of the related term, in a Termbase.
393
+ type:: Enum the relationship type (see <<relationship-types,Relationship Types>> below).
394
+ content:: String free-text content describing the related concept.
395
+ ref:: A <<citation,Citation>> reference to the related concept.
198
396
 
199
397
  There are two ways to initialize and populate a related concept
200
398
 
@@ -219,6 +417,208 @@ related_concept.content = "designation of the related concept"
219
417
  related_concept.ref = <Citation object>
220
418
  ----
221
419
 
420
+ [[relationship-types]]
421
+ ==== Relationship Types
422
+
423
+ Relationship types are drawn from ISO 10241-1, ISO 25964/SKOS, and ISO 12620/TBX. The table below shows each type with its provenance and cross-standard equivalents.
424
+
425
+ [cols="1,1,1,1,1"]
426
+ |===
427
+ |Glossarist type |Category |ISO 10241-1 |ISO 25964 / SKOS |ISO 12620 / TBX
428
+
429
+ |`deprecates`
430
+ |Lifecycle
431
+ |deprecates
432
+ |—
433
+ |—
434
+
435
+ |`supersedes`
436
+ |Lifecycle
437
+ |supersedes
438
+ |—
439
+ |—
440
+
441
+ |`superseded_by`
442
+ |Lifecycle
443
+ |superseded by
444
+ |—
445
+ |—
446
+
447
+ |`broader`
448
+ |Hierarchical
449
+ |broader concept
450
+ |BT (broaderTerm)
451
+ |broaderTerm
452
+
453
+ |`narrower`
454
+ |Hierarchical
455
+ |narrower concept
456
+ |NT (narrowerTerm)
457
+ |narrowerTerm
458
+
459
+ |`broader_generic`
460
+ |Hierarchical (generic)
461
+ |—
462
+ |BTG (broaderGeneric, is-a)
463
+ |broaderTermGeneric
464
+
465
+ |`narrower_generic`
466
+ |Hierarchical (generic)
467
+ |—
468
+ |NTG (narrowerGeneric)
469
+ |narrowerTermGeneric
470
+
471
+ |`broader_partitive`
472
+ |Hierarchical (partitive)
473
+ |—
474
+ |BTP (broaderPartitive, part-whole)
475
+ |broaderTermPartitive
476
+
477
+ |`narrower_partitive`
478
+ |Hierarchical (partitive)
479
+ |—
480
+ |NTP (narrowerPartitive)
481
+ |narrowerTermPartitive
482
+
483
+ |`broader_instantial`
484
+ |Hierarchical (instantial)
485
+ |—
486
+ |BTI (broaderInstantial, instance-of)
487
+ |broaderTermInstantial
488
+
489
+ |`narrower_instantial`
490
+ |Hierarchical (instantial)
491
+ |—
492
+ |NTI (narrowerInstantial)
493
+ |narrowerTermInstantial
494
+
495
+ |`equivalent`
496
+ |Equivalence
497
+ |equivalent
498
+ |exactMatch
499
+ |—
500
+
501
+ |`close_match`
502
+ |Approx. equiv.
503
+ |—
504
+ |closeMatch
505
+ |—
506
+
507
+ |`broad_match`
508
+ |Cross-vocab mapping
509
+ |—
510
+ |broadMatch
511
+ |—
512
+
513
+ |`narrow_match`
514
+ |Cross-vocab mapping
515
+ |—
516
+ |narrowMatch
517
+ |—
518
+
519
+ |`related_match`
520
+ |Cross-vocab mapping
521
+ |—
522
+ |relatedMatch
523
+ |—
524
+
525
+ |`compare`
526
+ |Comparative
527
+ |compare
528
+ |—
529
+ |—
530
+
531
+ |`contrast`
532
+ |Comparative
533
+ |contrast
534
+ |—
535
+ |—
536
+
537
+ |`see`
538
+ |Associative
539
+ |see also
540
+ |RT (relatedTerm)
541
+ |crossReference
542
+
543
+ |`related_concept`
544
+ |Associative
545
+ |—
546
+ |—
547
+ |relatedConcept
548
+
549
+ |`related_concept_broader`
550
+ |Associative (broader)
551
+ |—
552
+ |—
553
+ |relatedConceptBroader
554
+
555
+ |`related_concept_narrower`
556
+ |Associative (narrower)
557
+ |—
558
+ |—
559
+ |relatedConceptNarrower
560
+
561
+ |`sequentially_related_concept`
562
+ |Associative (sequential)
563
+ |—
564
+ |—
565
+ |sequentiallyRelatedConcept
566
+
567
+ |`spatially_related_concept`
568
+ |Associative (spatial)
569
+ |—
570
+ |—
571
+ |spatiallyRelatedConcept
572
+
573
+ |`temporally_related_concept`
574
+ |Associative (temporal)
575
+ |—
576
+ |—
577
+ |temporallyRelatedConcept
578
+
579
+ |`homograph`
580
+ |Lexical
581
+ |—
582
+ |—
583
+ |homograph
584
+
585
+ |`false_friend`
586
+ |Lexical
587
+ |—
588
+ |—
589
+ |falseFriend
590
+ |===
591
+
592
+ [[id,concept-reference]]
593
+ === ConceptReference
594
+
595
+ A typed reference to another concept, either local (within the same glossary) or external (in another concept registry).
596
+
597
+ term:: String — the display text for the referenced concept.
598
+ concept_id:: String — the identifier of the target concept.
599
+ source:: String — the registry URI prefix for external references (e.g. `urn:iec:std:iec:60050`).
600
+ ref_type:: String — the reference type: `local`, `designation`, or `urn`.
601
+ urn:: String — a direct URN for the target concept (e.g. `urn:iec:std:iec:60050-102-01-01`).
602
+
603
+ Local references use `concept_id` without `source`. External references use `source` + `concept_id` or a direct `urn`.
604
+
605
+ [,ruby]
606
+ ----
607
+ # Local reference
608
+ ref = Glossarist::ConceptReference.new(term: "latitude", concept_id: "200", ref_type: "local")
609
+
610
+ # External reference via URN
611
+ ref = Glossarist::ConceptReference.new(
612
+ term: "equality",
613
+ concept_id: "102-01-01",
614
+ source: "urn:iec:std:iec:60050",
615
+ ref_type: "urn",
616
+ )
617
+
618
+ ref.local? # => false
619
+ ref.external? # => true
620
+ ----
621
+
222
622
  [[id,concept-date]]
223
623
  === Concept Date
224
624
 
@@ -324,12 +724,27 @@ citation.clause = "some clause"
324
724
 
325
725
  === NonVerbRep
326
726
 
327
- Non-verbal Representation have the following fields
727
+ Non-verbal representations are associated resources (images, tables, formulas) used to help define a concept (ISO 10241-1 §6.5). They live outside the concept model and are referenced by URI. Resources can be shared across concepts and belong either to the dataset package (relative path) or are externally referenced (URL/URN).
328
728
 
329
- image:: An image used to help define a term.
330
- table:: A table used to help define a term.
331
- formula:: A formula used to help define a term.
332
- sources:: Bibliographic <<concept-source,concept source>> for the non-verbal representation of the term.
729
+ type:: String the type of representation: `image`, `table`, or `formula`.
730
+ ref:: String URI reference to the resource (relative path within the GCR package, URN, or URL).
731
+ text:: String optional text description or alt text.
732
+ sources:: Collection of <<concept-source,ConceptSource>> entries bibliographic sources for the representation.
733
+
734
+ Example:
735
+ +
736
+ [,yaml]
737
+ ----
738
+ non_verbal_rep:
739
+ - type: image
740
+ ref: assets/images/figure-1.svg
741
+ text: Diagram showing the concept hierarchy
742
+ - type: formula
743
+ ref: urn:gcr:assets:formula-eq1
744
+ sources:
745
+ - type: authoritative
746
+ status: identical
747
+ ----
333
748
 
334
749
  [[id,concept-source]]
335
750
  === ConceptSource
data/config.yml CHANGED
@@ -26,23 +26,90 @@ designation:
26
26
  base:
27
27
  normative_status:
28
28
  - preferred
29
- - deprecated
30
29
  - admitted
30
+ - deprecated
31
+ - superseded
31
32
  - <símbolo> # in iev-data => '<symbol>'
32
33
  - 티에스 # in iev-data => translates to 'TS' I think it is a synonym and not status.
33
34
  - prąd startowy # in iev-data => 'starting current' I think it is a synonym and not status.
35
+ relationship_type:
36
+ # Term-level (designation-to-designation within the same concept entry)
37
+ - abbreviated_form_for
38
+ - short_form_for
34
39
 
35
40
  related_concept:
36
41
  type:
42
+ # Lifecycle (ISO 10241-1)
37
43
  - deprecates
38
44
  - supersedes
39
45
  - superseded_by
46
+ # Hierarchical (ISO 10241-1 / ISO 25964)
40
47
  - narrower
41
48
  - broader
49
+ # Hierarchical sub-types — ISO 25964 generic (BTG/NTG)
50
+ - broader_generic
51
+ - narrower_generic
52
+ # Hierarchical sub-types — ISO 25964 partitive (BTP/NTP)
53
+ - broader_partitive
54
+ - narrower_partitive
55
+ # Hierarchical sub-types — ISO 25964 instantial (BTI/NTI)
56
+ - broader_instantial
57
+ - narrower_instantial
58
+ # Equivalence (ISO 10241-1 / ISO 25964 exactMatch / SKOS)
42
59
  - equivalent
60
+ # Approximate equivalence (ISO 25964 closeMatch / SKOS)
61
+ - close_match
62
+ # Cross-vocabulary mapping (SKOS)
63
+ - broad_match
64
+ - narrow_match
65
+ - related_match
66
+ # Comparative (ISO 10241-1)
43
67
  - compare
44
68
  - contrast
69
+ # Associative (ISO 10241-1 / ISO 25964 RT / TBX crossReference)
45
70
  - see
71
+ # Associative sub-types (ISO 25964 / TBX)
72
+ - related_concept
73
+ - related_concept_broader
74
+ - related_concept_narrower
75
+ # Associative — spatial/temporal (ISO 25964 / TBX)
76
+ - sequentially_related_concept
77
+ - spatially_related_concept
78
+ - temporally_related_concept
79
+ # Lexical (ISO 12620 / TBX)
80
+ - homograph
81
+ - false_friend
82
+
83
+ iso12620:
84
+ term_type:
85
+ # ISO 12620 term type classification for designations.
86
+ # Orthographic / structural:
87
+ - abbreviation
88
+ - acronym
89
+ - clipped_term
90
+ - full_form
91
+ - initialism
92
+ - short_form
93
+ - transliterated_form
94
+ - transcribed_form
95
+ - variant
96
+ # Symbolic / formulaic:
97
+ - equation
98
+ - formula
99
+ - logical_expression
100
+ - symbol
101
+ # Usage / provenance:
102
+ - common_name
103
+ - entry_term
104
+ - internationalism
105
+ - international_scientific_term
106
+ - part_number
107
+ - phraseological_unit
108
+ - shortcut
109
+ - sku
110
+ - standard_text
111
+ - synonym
112
+ - synonymous_phrase
46
113
 
47
114
  abbreviation:
48
115
  type:
@@ -4,7 +4,7 @@ module Glossarist
4
4
  attribute :id, :string
5
5
  attribute :uuid, :string
6
6
  attribute :subject, :string
7
- attribute :non_verb_rep, :string
7
+ attribute :non_verb_rep, NonVerbRep, collection: true
8
8
  attribute :extension_attributes, :string
9
9
  attribute :lineage_source, :string
10
10
  attribute :localizations, :hash
@@ -30,6 +30,8 @@ module Glossarist
30
30
  # Language code should be exactly 3 char long.
31
31
  # TODO: use min_length, max_length once added in lutaml-model
32
32
  attribute :language_code, :string, pattern: /^.{3}$/
33
+ attribute :script, :string
34
+ attribute :system, :string
33
35
  attribute :entry_status, :string
34
36
 
35
37
  key_value do
@@ -48,6 +50,8 @@ module Glossarist
48
50
  map :references, to: :references
49
51
  map :domain, to: :domain
50
52
  map %i[language_code languageCode], to: :language_code
53
+ map :script, to: :script
54
+ map :system, to: :system
51
55
  map %i[entry_status entryStatus], to: :entry_status
52
56
  map %i[review_date reviewDate], to: :review_date
53
57
  map %i[review_decision_date reviewDecisionDate], to: :review_decision_date
@@ -1,17 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Glossarist
4
+ # A typed reference to another concept, either local (within the same
5
+ # glossary) or external (in another concept registry).
6
+ #
7
+ # Local references use +concept_id+ without +source+. External references
8
+ # use +source+ (a registry URN prefix) and +concept_id+ to identify the
9
+ # target concept, or a direct +urn+ field for formal URN references.
4
10
  class ConceptReference < Lutaml::Model::Serializable
5
11
  attribute :term, :string
6
12
  attribute :concept_id, :string
7
13
  attribute :source, :string
8
14
  attribute :ref_type, :string
15
+ attribute :urn, :string
9
16
 
10
17
  key_value do
11
18
  map :term, to: :term
12
19
  map :concept_id, to: :concept_id
13
20
  map :source, to: :source
14
21
  map :ref_type, to: :ref_type
22
+ map :urn, to: :urn
23
+ end
24
+
25
+ def self.domain(concept_id)
26
+ new(concept_id: concept_id, ref_type: "domain")
15
27
  end
16
28
 
17
29
  def local?
@@ -23,25 +35,6 @@ module Glossarist
23
35
  !local?
24
36
  end
25
37
 
26
- def to_urn
27
- return nil unless external?
28
- return nil unless source && concept_id
29
-
30
- case source
31
- when /\Aurn:iec/ then "#{source}-#{concept_id}"
32
- when /\Aurn:iso/ then "#{source}:term:#{concept_id}"
33
- else "#{source}/#{concept_id}"
34
- end
35
- end
36
-
37
- def to_gcr_hash
38
- h = { "term" => term }
39
- h["concept_id"] = concept_id if concept_id
40
- h["source"] = source if source
41
- h["ref_type"] = ref_type if ref_type
42
- h.compact
43
- end
44
-
45
38
  def dedup_key
46
39
  concept_id ? [source, concept_id] : [source, concept_id, term]
47
40
  end
@@ -1,7 +1,6 @@
1
1
  module Glossarist
2
2
  module Designation
3
3
  class Abbreviation < Expression
4
- attribute :international, :boolean
5
4
  attribute :type, :string, default: -> { "abbreviation" }
6
5
 
7
6
  Glossarist::GlossaryDefinition::ABBREVIATION_TYPES.each do |name|
@@ -9,7 +8,6 @@ module Glossarist
9
8
  end
10
9
 
11
10
  key_value do
12
- map :international, to: :international
13
11
  map :type, to: :type, render_default: true
14
12
  Glossarist::GlossaryDefinition::ABBREVIATION_TYPES.each do |name|
15
13
  map name.to_sym, to: name.to_sym
@@ -6,12 +6,30 @@ module Glossarist
6
6
  attribute :normative_status, :string,
7
7
  values: Glossarist::GlossaryDefinition::DESIGNATION_BASE_NORMATIVE_STATUSES
8
8
  attribute :type, :string
9
+ attribute :language, :string
10
+ attribute :script, :string
11
+ attribute :system, :string
12
+ attribute :international, :boolean
13
+ attribute :absent, :boolean
14
+ attribute :pronunciation, Pronunciation, collection: true
15
+ attribute :sources, ConceptSource, collection: true
16
+ attribute :term_type, :string
17
+ attribute :related, RelatedConcept, collection: true
9
18
 
10
19
  key_value do
11
20
  map :type, to: :type
12
21
  map %i[normative_status normativeStatus], to: :normative_status
13
22
  map %i[geographical_area geographicalArea], to: :geographical_area
14
23
  map :designation, to: :designation
24
+ map :language, to: :language
25
+ map :script, to: :script
26
+ map :system, to: :system
27
+ map :international, to: :international
28
+ map :absent, to: :absent
29
+ map :pronunciation, to: :pronunciation
30
+ map :sources, to: :sources
31
+ map %i[term_type termType], to: :term_type
32
+ map :related, to: :related
15
33
  end
16
34
 
17
35
  def self.of_yaml(hash, options = {})
@@ -34,7 +52,9 @@ module Glossarist
34
52
  end
35
53
 
36
54
  def self.infer_designation_type(hash)
37
- if hash["international"] || hash["abbreviation_type"]
55
+ if hash["abbreviation_type"]
56
+ "abbreviation"
57
+ elsif hash["international"]
38
58
  "symbol"
39
59
  else
40
60
  "expression"
@@ -5,6 +5,7 @@ module Glossarist
5
5
  class Expression < Base
6
6
  attribute :prefix, :string
7
7
  attribute :usage_info, :string
8
+ attribute :field_of_application, :string
8
9
 
9
10
  attribute :gender, :string
10
11
  attribute :plurality, :string
@@ -16,6 +17,8 @@ module Glossarist
16
17
  map :type, to: :type, render_default: true
17
18
  map :prefix, to: :prefix
18
19
  map %i[usage_info usageInfo], to: :usage_info
20
+ map %i[field_of_application fieldOfApplication],
21
+ to: :field_of_application
19
22
  map %i[grammar_info grammarInfo], to: :grammar_info
20
23
  end
21
24
 
@@ -2,13 +2,9 @@ module Glossarist
2
2
  module Designation
3
3
  class LetterSymbol < Symbol
4
4
  attribute :text, :string
5
- attribute :language, :string
6
- attribute :script, :string
7
5
 
8
6
  key_value do
9
7
  map :text, to: :text
10
- map :language, to: :language
11
- map :script, to: :script
12
8
  end
13
9
 
14
10
  def self.of_yaml(hash, options = {})
@@ -1,11 +1,9 @@
1
1
  module Glossarist
2
2
  module Designation
3
3
  class Symbol < Base
4
- attribute :international, :boolean
5
4
  attribute :type, :string, default: -> { "symbol" }
6
5
 
7
6
  key_value do
8
- map :international, to: :international
9
7
  map :type, to: :type, render_default: true
10
8
  end
11
9
 
@@ -28,5 +28,10 @@ module Glossarist
28
28
  CONCEPT_DATE_TYPES = config.dig("concept_date", "type").freeze
29
29
 
30
30
  CONCEPT_STATUSES = config.dig("concept", "status").freeze
31
+
32
+ DESIGNATION_RELATIONSHIP_TYPES = config.dig("designation",
33
+ "relationship_type")&.freeze
34
+
35
+ ISO12620_TERM_TYPES = config.dig("iso12620", "term_type").freeze
31
36
  end
32
37
  end
@@ -5,7 +5,7 @@ module Glossarist
5
5
  attribute :id, :string
6
6
  attribute :uri, :string
7
7
  attribute :localized_concepts, :hash
8
- attribute :groups, :string, collection: true
8
+ attribute :domains, ConceptReference, collection: true
9
9
  attribute :sources, ConceptSource, collection: true
10
10
  attribute :localizations, LocalizedConcept,
11
11
  collection: Collections::LocalizationCollection,
@@ -16,7 +16,8 @@ module Glossarist
16
16
  with: { to: :id_to_yaml, from: :id_from_yaml }
17
17
  map :uri, to: :uri
18
18
  map %i[localized_concepts localizedConcepts], to: :localized_concepts
19
- map :groups, to: :groups
19
+ map %i[domains groups], to: :domains,
20
+ with: { from: :domains_from_yaml, to: :domains_to_yaml }
20
21
  map :sources, to: :sources
21
22
  map :localizations, to: :localizations,
22
23
  with: { from: :localizations_from_yaml, to: :localizations_to_yaml }
@@ -41,6 +42,24 @@ module Glossarist
41
42
 
42
43
  def localizations_to_yaml(model, doc); end
43
44
 
45
+ def domains_from_yaml(model, value)
46
+ return unless value.is_a?(Array)
47
+
48
+ model.domains = value.map do |item|
49
+ if item.is_a?(Hash)
50
+ ConceptReference.of_yaml(item)
51
+ else
52
+ ConceptReference.new(concept_id: item.to_s, ref_type: "domain")
53
+ end
54
+ end
55
+ end
56
+
57
+ def domains_to_yaml(model, doc)
58
+ return if model.domains.nil? || model.domains.empty?
59
+
60
+ doc["domains"] = model.domains.map(&:to_hash)
61
+ end
62
+
44
63
  def authoritative_source
45
64
  return [] unless sources
46
65
 
@@ -1,14 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Glossarist
4
+ # A non-verbal representation used to help define a concept, following
5
+ # ISO 10241-1 §6.5.
6
+ #
7
+ # Non-verbal representations are associated resources (images, tables,
8
+ # formulas) that live outside the concept model. They are referenced by URI
9
+ # and can be shared across concepts. The resource belongs either to the
10
+ # dataset package (relative path) or is externally referenced (URL/URN).
11
+ #
12
+ # Each non-verbal representation specifies:
13
+ # - +type+: one of "image", "table", "formula"
14
+ # - +ref+: URI reference to the resource (relative path, URN, or URL)
15
+ # - +text+: optional text description or alt text
16
+ # - +sources+: bibliographic sources for the representation
2
17
  class NonVerbRep < Lutaml::Model::Serializable
3
- attribute :image, :string
4
- attribute :table, :string
5
- attribute :formula, :string
18
+ attribute :type, :string
19
+ attribute :ref, :string
20
+ attribute :text, :string
6
21
  attribute :sources, ConceptSource, collection: true
7
22
 
8
23
  key_value do
9
- map :image, to: :image
10
- map :table, to: :table
11
- map :formula, to: :formula
24
+ map :type, to: :type
25
+ map :ref, to: :ref
26
+ map :text, to: :text
12
27
  map :sources, to: :sources
13
28
  end
14
29
  end
@@ -0,0 +1,32 @@
1
+ module Glossarist
2
+ # A pronunciation or transcription of a designation, following ISO 24229
3
+ # spelling system conventions.
4
+ #
5
+ # Each pronunciation entry specifies the text of the pronunciation and the
6
+ # context in which it is expressed:
7
+ # - +language+ (ISO 639) identifies the language or dialect being pronounced
8
+ # - +script+ (ISO 15924) identifies the script used for the pronunciation text
9
+ # - +country+ (ISO 3166-1) identifies the country variant
10
+ # - +system+ identifies the transcription/romanization system used (ISO 24229
11
+ # conversion system code or a simple identifier like "IPA")
12
+ #
13
+ # A designation can have multiple pronunciations, e.g.:
14
+ # - IPA: { content: "toːkjoː", script: "Latn", language: "jpn", system: "IPA" }
15
+ # - Hepburn: { content: "Tōkyō", script: "Latn", language: "jpn", system: "Var:jpn-Hrkt:Latn:Hepburn-1886" }
16
+ # - Cyrillic: { content: "Токио", script: "Cyrl", language: "rus", system: "polivanov" }
17
+ class Pronunciation < Lutaml::Model::Serializable
18
+ attribute :content, :string
19
+ attribute :language, :string
20
+ attribute :script, :string
21
+ attribute :country, :string
22
+ attribute :system, :string
23
+
24
+ key_value do
25
+ map :content, to: :content
26
+ map :language, to: :language
27
+ map :script, to: :script
28
+ map :country, to: :country
29
+ map :system, to: :system
30
+ end
31
+ end
32
+ end
@@ -157,11 +157,9 @@ module Glossarist
157
157
  refs = []
158
158
 
159
159
  concept.localizations.each do |l10n|
160
- nvr = l10n.non_verb_rep
161
- if nvr.is_a?(String) && !nvr.strip.empty?
162
- nvr.strip.split.each do |p|
163
- refs << AssetReference.new(path: p) unless p.empty?
164
- end
160
+ Array(l10n.non_verb_rep).each do |nvr|
161
+ next unless nvr.is_a?(NonVerbRep) && nvr.ref && !nvr.ref.strip.empty?
162
+ refs << AssetReference.new(path: nvr.ref.strip)
165
163
  end
166
164
 
167
165
  (l10n.data&.terms || []).each do |term|
@@ -64,7 +64,19 @@ module Glossarist
64
64
  def to_urn(urn_or_reference)
65
65
  case urn_or_reference
66
66
  when String then urn_or_reference
67
- when ConceptReference then urn_or_reference.to_urn
67
+ when ConceptReference then concept_reference_to_urn(urn_or_reference)
68
+ end
69
+ end
70
+
71
+ def concept_reference_to_urn(ref)
72
+ return ref.urn if ref.urn && !ref.urn.strip.empty?
73
+ return nil unless ref.external?
74
+ return nil unless ref.source && ref.concept_id
75
+
76
+ case ref.source
77
+ when /\Aurn:iec/ then "#{ref.source}-#{ref.concept_id}"
78
+ when /\Aurn:iso/ then "#{ref.source}:term:#{ref.concept_id}"
79
+ else "#{ref.source}/#{ref.concept_id}"
68
80
  end
69
81
  end
70
82
  end
@@ -42,6 +42,7 @@ module Glossarist
42
42
  mc.add_localization(LocalizedConcept.of_yaml({ "data" => data }))
43
43
  end
44
44
 
45
+ assign_domains(mc) if groups.is_a?(Array) && groups.any?
45
46
  assign_references(mc) if references.is_a?(Array) && references.any?
46
47
 
47
48
  mc
@@ -49,6 +50,12 @@ module Glossarist
49
50
 
50
51
  private
51
52
 
53
+ def assign_domains(concept)
54
+ concept.data.domains = groups.map do |g|
55
+ ConceptReference.new(concept_id: g.to_s, ref_type: "domain")
56
+ end
57
+ end
58
+
52
59
  def assign_references(concept)
53
60
  l10n = concept.localization("eng") || concept.localizations.values.first
54
61
  return unless l10n
@@ -94,10 +94,11 @@ module Glossarist
94
94
  end
95
95
 
96
96
  def register_non_verb_rep(index, l10n)
97
- nvr = l10n.non_verb_rep
98
- return unless nvr.is_a?(String) && !nvr.strip.empty?
97
+ Array(l10n.non_verb_rep).each do |nvr|
98
+ next unless nvr.is_a?(NonVerbRep) && nvr.ref && !nvr.ref.strip.empty?
99
99
 
100
- nvr.strip.split.each { |p| index.register(p) }
100
+ index.register(nvr.ref.strip)
101
+ end
101
102
  end
102
103
 
103
104
  def register_graphical_symbols(index, l10n)
@@ -4,5 +4,5 @@
4
4
  #
5
5
 
6
6
  module Glossarist
7
- VERSION = "2.6.5"
7
+ VERSION = "2.6.6"
8
8
  end
data/lib/glossarist.rb CHANGED
@@ -52,6 +52,7 @@ module Glossarist
52
52
  autoload :ManagedConceptCollection, "glossarist/managed_concept_collection"
53
53
  autoload :ManagedConceptData, "glossarist/managed_concept_data"
54
54
  autoload :NonVerbRep, "glossarist/non_verb_rep"
55
+ autoload :Pronunciation, "glossarist/pronunciation"
55
56
  autoload :RelatedConcept, "glossarist/related_concept"
56
57
  autoload :Rdf, "glossarist/rdf"
57
58
  autoload :Sts, "glossarist/sts"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glossarist
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.5
4
+ version: 2.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-12 00:00:00.000000000 Z
11
+ date: 2026-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -192,6 +192,7 @@ files:
192
192
  - lib/glossarist/managed_concept_collection.rb
193
193
  - lib/glossarist/managed_concept_data.rb
194
194
  - lib/glossarist/non_verb_rep.rb
195
+ - lib/glossarist/pronunciation.rb
195
196
  - lib/glossarist/rdf.rb
196
197
  - lib/glossarist/rdf/localized_literal.rb
197
198
  - lib/glossarist/rdf/namespaces.rb