glossarist-new 1.0.0
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 +7 -0
- data/.editorconfig +15 -0
- data/.github/workflows/test.yml +34 -0
- data/.gitignore +18 -0
- data/.hound.yml +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +35 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +23 -0
- data/README.adoc +11 -0
- data/Rakefile +8 -0
- data/config.yml +83 -0
- data/glossarist.gemspec +36 -0
- data/lib/glossarist/citation.rb +85 -0
- data/lib/glossarist/collection.rb +86 -0
- data/lib/glossarist/concept.rb +143 -0
- data/lib/glossarist/concept_date.rb +20 -0
- data/lib/glossarist/concept_manager.rb +44 -0
- data/lib/glossarist/concept_source.rb +62 -0
- data/lib/glossarist/designation/abbreviation.rb +23 -0
- data/lib/glossarist/designation/base.rb +37 -0
- data/lib/glossarist/designation/expression.rb +50 -0
- data/lib/glossarist/designation/grammar_info.rb +58 -0
- data/lib/glossarist/designation/graphical_symbol.rb +17 -0
- data/lib/glossarist/designation/letter_symbol.rb +19 -0
- data/lib/glossarist/designation/symbol.rb +21 -0
- data/lib/glossarist/designation.rb +27 -0
- data/lib/glossarist/detailed_definition.rb +31 -0
- data/lib/glossarist/glossary_definition.rb +29 -0
- data/lib/glossarist/localized_concept.rb +61 -0
- data/lib/glossarist/managed_concept.rb +107 -0
- data/lib/glossarist/managed_concept_collection.rb +79 -0
- data/lib/glossarist/model.rb +29 -0
- data/lib/glossarist/non_verb_rep.rb +18 -0
- data/lib/glossarist/related_concept.rb +31 -0
- data/lib/glossarist/utilities/boolean_attributes.rb +35 -0
- data/lib/glossarist/utilities/common_functions.rb +29 -0
- data/lib/glossarist/utilities/enum/class_methods.rb +99 -0
- data/lib/glossarist/utilities/enum/enum_collection.rb +45 -0
- data/lib/glossarist/utilities/enum/instance_methods.rb +55 -0
- data/lib/glossarist/utilities/enum.rb +21 -0
- data/lib/glossarist/utilities.rb +5 -0
- data/lib/glossarist/version.rb +8 -0
- data/lib/glossarist.rb +31 -0
- metadata +131 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glossarist
|
4
|
+
class ConceptSource < Model
|
5
|
+
include Glossarist::Utilities::Enum
|
6
|
+
include Glossarist::Utilities::CommonFunctions
|
7
|
+
|
8
|
+
register_enum :status, Glossarist::GlossaryDefinition::CONCEPT_SOURCE_STATUSES
|
9
|
+
register_enum :type, Glossarist::GlossaryDefinition::CONCEPT_SOURCE_TYPES
|
10
|
+
|
11
|
+
attr_reader :origin
|
12
|
+
alias_method :ref, :origin
|
13
|
+
|
14
|
+
attr_accessor :modification
|
15
|
+
|
16
|
+
def initialize(attributes = {})
|
17
|
+
if rel = attributes.delete("relationship")
|
18
|
+
self.status = rel["type"]
|
19
|
+
self.modification = rel["modification"]
|
20
|
+
end
|
21
|
+
|
22
|
+
self.origin = slice_keys(attributes, ref_param_names)
|
23
|
+
|
24
|
+
remaining_attributes = attributes.dup
|
25
|
+
ref_param_names.each { |k| remaining_attributes.delete(k) }
|
26
|
+
|
27
|
+
super(remaining_attributes)
|
28
|
+
end
|
29
|
+
|
30
|
+
def origin=(origin)
|
31
|
+
@origin = Citation.new(origin)
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :ref=, :origin=
|
35
|
+
|
36
|
+
def to_h
|
37
|
+
origin_hash = self.origin.to_h.empty? ? nil : self.origin.to_h
|
38
|
+
|
39
|
+
{
|
40
|
+
"type" => type.to_s,
|
41
|
+
"status" => status&.to_s,
|
42
|
+
"origin" => origin_hash,
|
43
|
+
"modification" => modification,
|
44
|
+
}.compact
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def ref_param_names
|
50
|
+
%w[
|
51
|
+
ref
|
52
|
+
text
|
53
|
+
source
|
54
|
+
id
|
55
|
+
version
|
56
|
+
clause
|
57
|
+
link
|
58
|
+
original
|
59
|
+
]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "expression"
|
4
|
+
require_relative "../utilities"
|
5
|
+
|
6
|
+
module Glossarist
|
7
|
+
module Designation
|
8
|
+
class Abbreviation < Expression
|
9
|
+
include Glossarist::Utilities::Enum
|
10
|
+
|
11
|
+
register_enum :type, Glossarist::GlossaryDefinition::ABBREVIATION_TYPES
|
12
|
+
|
13
|
+
attr_accessor :international
|
14
|
+
|
15
|
+
def to_h
|
16
|
+
super().merge({
|
17
|
+
"type" => type.to_s,
|
18
|
+
"international" => international,
|
19
|
+
}).compact
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glossarist
|
4
|
+
module Designation
|
5
|
+
class Base < Model
|
6
|
+
include Glossarist::Utilities::Enum
|
7
|
+
|
8
|
+
# @note This is not entirely aligned with agreed schema and may be
|
9
|
+
# changed.
|
10
|
+
attr_accessor :designation
|
11
|
+
|
12
|
+
attr_accessor :geographical_area
|
13
|
+
register_enum :normative_status, Glossarist::GlossaryDefinition::DESIGNATION_BASE_NORMATIVE_STATUSES
|
14
|
+
|
15
|
+
def self.from_h(hash)
|
16
|
+
type = hash["type"]
|
17
|
+
|
18
|
+
if type.nil? || /\w/ !~ type
|
19
|
+
raise ArgumentError, "designation type is missing"
|
20
|
+
end
|
21
|
+
|
22
|
+
designation_subclass = SERIALIZED_TYPES[type]
|
23
|
+
|
24
|
+
if self == Base
|
25
|
+
# called on Base class, delegate it to proper subclass
|
26
|
+
SERIALIZED_TYPES[type].from_h(hash)
|
27
|
+
else
|
28
|
+
# called on subclass, instantiate object
|
29
|
+
unless SERIALIZED_TYPES[self] == type
|
30
|
+
raise ArgumentError, "unexpected designation type: #{type}"
|
31
|
+
end
|
32
|
+
super(hash.reject { |k, _| k == "type" })
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module Glossarist
|
6
|
+
module Designation
|
7
|
+
class Expression < Base
|
8
|
+
attr_accessor :prefix
|
9
|
+
attr_accessor :usage_info
|
10
|
+
|
11
|
+
# List of grammar info.
|
12
|
+
# @return [Array<GrammarInfo>]
|
13
|
+
attr_reader :grammar_info
|
14
|
+
|
15
|
+
def grammar_info=(grammar_info)
|
16
|
+
@grammar_info = grammar_info.map { |g| GrammarInfo.new(g) }
|
17
|
+
end
|
18
|
+
|
19
|
+
# @todo Added to cater for current iev-data implementation,
|
20
|
+
# might be removed in the future.
|
21
|
+
def self.from_h(hash)
|
22
|
+
gender = hash.delete("gender") || hash.delete(:gender)
|
23
|
+
number = hash.delete("plurality") || hash.delete(:plurality)
|
24
|
+
part_of_speech = hash.delete("part_of_speech") || hash.delete(:part_of_speech)
|
25
|
+
|
26
|
+
if gender || number || part_of_speech
|
27
|
+
hash["grammar_info"] = [{
|
28
|
+
"gender" => gender,
|
29
|
+
"number" => number,
|
30
|
+
part_of_speech => part_of_speech,
|
31
|
+
}.compact]
|
32
|
+
end
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_h
|
38
|
+
{
|
39
|
+
"type" => "expression",
|
40
|
+
"prefix" => prefix,
|
41
|
+
"normative_status" => normative_status,
|
42
|
+
"usage_info" => usage_info,
|
43
|
+
"designation" => designation,
|
44
|
+
"geographical_area" => geographical_area,
|
45
|
+
"grammar_info" => grammar_info&.map(&:to_h),
|
46
|
+
}.compact
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../utilities"
|
4
|
+
|
5
|
+
module Glossarist
|
6
|
+
module Designation
|
7
|
+
class GrammarInfo
|
8
|
+
include Glossarist::Utilities::Enum
|
9
|
+
include Glossarist::Utilities::BooleanAttributes
|
10
|
+
include Glossarist::Utilities::CommonFunctions
|
11
|
+
|
12
|
+
register_enum :gender, Glossarist::GlossaryDefinition::GRAMMAR_INFO_GENDERS, multiple: true
|
13
|
+
register_enum :number, Glossarist::GlossaryDefinition::GRAMMAR_INFO_NUMBERS, multiple: true
|
14
|
+
|
15
|
+
register_boolean_attributes Glossarist::GlossaryDefinition::GRAMMAR_INFO_BOOLEAN_ATTRIBUTES
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
sanitized_options(options).each do |attr, value|
|
19
|
+
public_send("#{attr}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def part_of_speech=(pos)
|
24
|
+
public_send("#{pos}=", pos)
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_h
|
28
|
+
{
|
29
|
+
"preposition" => preposition?,
|
30
|
+
"participle" => participle?,
|
31
|
+
"adj" => adj?,
|
32
|
+
"verb" => verb?,
|
33
|
+
"adverb" => adverb?,
|
34
|
+
"noun" => noun?,
|
35
|
+
"gender" => gender,
|
36
|
+
"number" => number,
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def sanitized_options(options)
|
43
|
+
hash = symbolize_keys(options)
|
44
|
+
slice_keys(hash, [
|
45
|
+
:gender,
|
46
|
+
:number,
|
47
|
+
:preposition,
|
48
|
+
:participle,
|
49
|
+
:adj,
|
50
|
+
:verb,
|
51
|
+
:adverb,
|
52
|
+
:noun,
|
53
|
+
:part_of_speech,
|
54
|
+
])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glossarist
|
4
|
+
module Designation
|
5
|
+
class GraphicalSymbol < Symbol
|
6
|
+
attr_accessor :text
|
7
|
+
attr_accessor :image
|
8
|
+
|
9
|
+
def to_h
|
10
|
+
super.merge(
|
11
|
+
"text" => text,
|
12
|
+
"image" => image,
|
13
|
+
)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glossarist
|
4
|
+
module Designation
|
5
|
+
class LetterSymbol < Symbol
|
6
|
+
attr_accessor :text
|
7
|
+
attr_accessor :language
|
8
|
+
attr_accessor :script
|
9
|
+
|
10
|
+
def to_h
|
11
|
+
super.merge(
|
12
|
+
"text" => text,
|
13
|
+
"language" => language,
|
14
|
+
"script" => script,
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module Glossarist
|
6
|
+
module Designation
|
7
|
+
class Symbol < Base
|
8
|
+
attr_accessor :international
|
9
|
+
|
10
|
+
def to_h
|
11
|
+
{
|
12
|
+
"type" => Glossarist::Designation::SERIALIZED_TYPES[self.class],
|
13
|
+
"normative_status" => normative_status,
|
14
|
+
"geographical_area" => geographical_area,
|
15
|
+
"designation" => designation,
|
16
|
+
"international" => international,
|
17
|
+
}.compact
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (c) Copyright 2021 Ribose Inc.
|
4
|
+
#
|
5
|
+
|
6
|
+
require_relative "designation/abbreviation"
|
7
|
+
require_relative "designation/base"
|
8
|
+
require_relative "designation/expression"
|
9
|
+
require_relative "designation/grammar_info"
|
10
|
+
require_relative "designation/symbol"
|
11
|
+
require_relative "designation/graphical_symbol"
|
12
|
+
require_relative "designation/letter_symbol"
|
13
|
+
|
14
|
+
module Glossarist
|
15
|
+
module Designation
|
16
|
+
# Bi-directional class-to-string mapping for STI-like serialization.
|
17
|
+
SERIALIZED_TYPES = {
|
18
|
+
Expression => "expression",
|
19
|
+
Symbol => "symbol",
|
20
|
+
Abbreviation => "abbreviation",
|
21
|
+
GraphicalSymbol => "graphical_symbol",
|
22
|
+
LetterSymbol => "letter_symbol",
|
23
|
+
}
|
24
|
+
.tap { |h| h.merge!(h.invert) }
|
25
|
+
.freeze
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glossarist
|
4
|
+
class DetailedDefinition < Model
|
5
|
+
|
6
|
+
def initialize(attributes = {})
|
7
|
+
if attributes.is_a?(Hash)
|
8
|
+
super
|
9
|
+
else
|
10
|
+
self.content = attributes
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [String]
|
15
|
+
attr_accessor :content
|
16
|
+
|
17
|
+
# @return [Array<ConceptSource>]
|
18
|
+
attr_reader :sources
|
19
|
+
|
20
|
+
def sources=(sources)
|
21
|
+
@sources = sources.map { |s| ConceptSource.new(s) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
{
|
26
|
+
"content" => content,
|
27
|
+
"sources" => sources&.map(&:to_h),
|
28
|
+
}.compact
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module Glossarist
|
6
|
+
module GlossaryDefinition
|
7
|
+
config = YAML.load_file(File.expand_path("../../../config.yml", __FILE__)) || {}
|
8
|
+
|
9
|
+
CONCEPT_SOURCE_STATUSES = config.dig("concept_source", "status").freeze
|
10
|
+
|
11
|
+
CONCEPT_SOURCE_TYPES = config.dig("concept_source", "type").freeze
|
12
|
+
|
13
|
+
RELATED_CONCEPT_TYPES = config.dig("related_concept", "type").freeze
|
14
|
+
|
15
|
+
ABBREVIATION_TYPES = config.dig("abbreviation", "type").freeze
|
16
|
+
|
17
|
+
GRAMMAR_INFO_BOOLEAN_ATTRIBUTES = config.dig("grammar_info", "boolean_attribute").freeze
|
18
|
+
|
19
|
+
GRAMMAR_INFO_GENDERS = config.dig("grammar_info", "gender").freeze
|
20
|
+
|
21
|
+
GRAMMAR_INFO_NUMBERS = config.dig("grammar_info", "number").freeze
|
22
|
+
|
23
|
+
DESIGNATION_BASE_NORMATIVE_STATUSES = config.dig("designation", "base", "normative_status").freeze
|
24
|
+
|
25
|
+
CONCEPT_DATE_TYPES = config.dig("concept_date", "type").freeze
|
26
|
+
|
27
|
+
CONCEPT_STATUSES = config.dig("concept", "status").freeze
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (c) Copyright 2021 Ribose Inc.
|
4
|
+
#
|
5
|
+
|
6
|
+
module Glossarist
|
7
|
+
class LocalizedConcept < Concept
|
8
|
+
# ISO 639-2 code for terminology.
|
9
|
+
# @see https://www.loc.gov/standards/iso639-2/php/code_list.php code list
|
10
|
+
# @return [String]
|
11
|
+
attr_accessor :language_code
|
12
|
+
|
13
|
+
# Must be one of the following:
|
14
|
+
# +notValid+, +valid+, +superseded+, +retired+.
|
15
|
+
# @todo Proper type checking.
|
16
|
+
# @note Works with strings, but soon they may be replaced with symbols.
|
17
|
+
# @return [String]
|
18
|
+
attr_accessor :entry_status
|
19
|
+
|
20
|
+
# Must be one of the following:
|
21
|
+
# +preferred+, +admitted+, +deprecated+.
|
22
|
+
# @todo Proper type checking.
|
23
|
+
# @note Works with strings, but soon they may be replaced with symbols.
|
24
|
+
# @return [String]
|
25
|
+
attr_accessor :classification
|
26
|
+
|
27
|
+
attr_accessor :review_date
|
28
|
+
attr_accessor :review_decision_date
|
29
|
+
attr_accessor :review_decision_event
|
30
|
+
|
31
|
+
def initialize(*)
|
32
|
+
@examples = []
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_h # rubocop:disable Metrics/MethodLength
|
38
|
+
super.merge({
|
39
|
+
"language_code" => language_code,
|
40
|
+
"entry_status" => entry_status,
|
41
|
+
"sources" => sources.empty? ? nil : sources&.map(&:to_h),
|
42
|
+
"classification" => classification,
|
43
|
+
"dates" => dates&.map(&:to_h),
|
44
|
+
"review_date" => review_date,
|
45
|
+
"review_decision_date" => review_decision_date,
|
46
|
+
"review_decision_event" => review_decision_event,
|
47
|
+
}.compact)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.from_h(hash)
|
51
|
+
terms = hash["terms"]&.map { |h| Designation::Base.from_h(h) } || []
|
52
|
+
sources = hash["authoritative_source"]&.each { |source| source.merge({ "type" => "authoritative"}) }
|
53
|
+
|
54
|
+
super(hash.merge({"terms" => terms, "sources" => sources}))
|
55
|
+
end
|
56
|
+
|
57
|
+
# @deprecated For legacy reasons only.
|
58
|
+
# Implicit conversion (i.e. {#to_hash} alias) will be removed soon.
|
59
|
+
alias :to_hash :to_h
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glossarist
|
4
|
+
class ManagedConcept < Model
|
5
|
+
include Glossarist::Utilities::Enum
|
6
|
+
include Glossarist::Utilities::CommonFunctions
|
7
|
+
|
8
|
+
# @return [String]
|
9
|
+
attr_accessor :id
|
10
|
+
alias :termid= :id=
|
11
|
+
|
12
|
+
# @return [Array<RelatedConcept>]
|
13
|
+
attr_reader :related
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
register_enum :status, Glossarist::GlossaryDefinition::CONCEPT_STATUSES
|
17
|
+
|
18
|
+
# return [Array<ConceptDate>]
|
19
|
+
attr_reader :dates
|
20
|
+
|
21
|
+
# return [Array<LocalizedConcept>]
|
22
|
+
attr_reader :localized_concepts
|
23
|
+
|
24
|
+
# All localizations for this concept.
|
25
|
+
#
|
26
|
+
# Keys are language codes and values are instances of {LocalizedConcept}.
|
27
|
+
# @return [Hash<String, LocalizedConcept>]
|
28
|
+
attr_accessor :localizations
|
29
|
+
|
30
|
+
def initialize(attributes = {})
|
31
|
+
@localizations = {}
|
32
|
+
self.localized_concepts = attributes.values.grep(Hash)
|
33
|
+
|
34
|
+
attributes = symbolize_keys(attributes)
|
35
|
+
super(slice_keys(attributes, managed_concept_attributes))
|
36
|
+
end
|
37
|
+
|
38
|
+
def localized_concepts=(localized_concepts_hash)
|
39
|
+
@localized_concepts = localized_concepts_hash.map { |l| LocalizedConcept.new(l) }.compact
|
40
|
+
|
41
|
+
@localized_concepts.each do |l|
|
42
|
+
add_l10n(l)
|
43
|
+
end
|
44
|
+
|
45
|
+
@localized_concepts
|
46
|
+
end
|
47
|
+
|
48
|
+
def related=(related)
|
49
|
+
@related = related&.map { |r| RelatedConcept.new(r) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def dates=(dates)
|
53
|
+
@dates = dates&.map { |d| ConceptDate.new(d) }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Adds concept localization.
|
57
|
+
# @param localized_concept [LocalizedConcept]
|
58
|
+
def add_localization(localized_concept)
|
59
|
+
lang = localized_concept.language_code
|
60
|
+
localizations.store(lang, localized_concept)
|
61
|
+
end
|
62
|
+
|
63
|
+
alias :add_l10n :add_localization
|
64
|
+
|
65
|
+
# Returns concept localization.
|
66
|
+
# @param lang [String] language code
|
67
|
+
# @return [LocalizedConcept]
|
68
|
+
def localization(lang)
|
69
|
+
localizations[lang]
|
70
|
+
end
|
71
|
+
|
72
|
+
alias :l10n :localization
|
73
|
+
|
74
|
+
def to_h
|
75
|
+
{
|
76
|
+
"termid" => id,
|
77
|
+
"term" => default_designation,
|
78
|
+
"related" => related&.map(&:to_h),
|
79
|
+
"dates" => dates&.empty? ? nil : dates&.map(&:to_h),
|
80
|
+
}.merge(localizations.transform_values(&:to_h)).compact
|
81
|
+
end
|
82
|
+
|
83
|
+
def default_designation
|
84
|
+
localized = localization("eng") || localizations.values.first
|
85
|
+
localized&.terms&.first&.designation
|
86
|
+
end
|
87
|
+
|
88
|
+
def managed_concept_attributes
|
89
|
+
%i[
|
90
|
+
id
|
91
|
+
termid
|
92
|
+
related
|
93
|
+
status
|
94
|
+
dates
|
95
|
+
localized_concepts
|
96
|
+
].compact
|
97
|
+
end
|
98
|
+
|
99
|
+
Glossarist::GlossaryDefinition::RELATED_CONCEPT_TYPES.each do |type|
|
100
|
+
# List of related concepts of the specified type.
|
101
|
+
# @return [Array<RelatedConcept>]
|
102
|
+
define_method("#{type}_concepts") do
|
103
|
+
related&.select { |concept| concept.type == type.to_s } || []
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glossarist
|
4
|
+
class ManagedConceptCollection
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@managed_concepts = {}
|
9
|
+
@concept_manager = ConceptManager.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Array<ManagedConcept>]
|
13
|
+
def managed_concepts
|
14
|
+
@managed_concepts.values
|
15
|
+
end
|
16
|
+
|
17
|
+
def managed_concepts=(managed_concepts = [])
|
18
|
+
managed_concepts.each do |managed_concept|
|
19
|
+
store(ManagedConcept.new(managed_concept))
|
20
|
+
end
|
21
|
+
|
22
|
+
@managed_concepts.values
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_h
|
26
|
+
{
|
27
|
+
"managed_concepts" => managed_concepts.map(&:to_h),
|
28
|
+
}.compact
|
29
|
+
end
|
30
|
+
|
31
|
+
def each(&block)
|
32
|
+
@managed_concepts.each_value(&block)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns concept with given ID, if it is present in collection, or +nil+
|
36
|
+
# otherwise.
|
37
|
+
#
|
38
|
+
# @param id [String]
|
39
|
+
# ManagedConcept ID
|
40
|
+
# @return [ManagedConcept, nil]
|
41
|
+
def fetch(id)
|
42
|
+
@managed_concepts[id]
|
43
|
+
end
|
44
|
+
|
45
|
+
alias :[] :fetch
|
46
|
+
|
47
|
+
# If ManagedConcept with given ID is present in this collection, then
|
48
|
+
# returns it. Otherwise, instantiates a new ManagedConcept, adds it to
|
49
|
+
# the collection, and returns it.
|
50
|
+
#
|
51
|
+
# @param id [String]
|
52
|
+
# ManagedConcept ID
|
53
|
+
# @return [ManagedConcept]
|
54
|
+
def fetch_or_initialize(id)
|
55
|
+
fetch(id) or store(ManagedConcept.new(id: id))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Adds concept to the collection. If collection contains a concept with
|
59
|
+
# the same ID already, that concept is replaced.
|
60
|
+
#
|
61
|
+
# @param managed_concept [ManagedConcept]
|
62
|
+
# ManagedConcept about to be added
|
63
|
+
def store(managed_concept)
|
64
|
+
@managed_concepts[managed_concept.id] = managed_concept
|
65
|
+
end
|
66
|
+
|
67
|
+
alias :<< :store
|
68
|
+
|
69
|
+
def load_from_files(path)
|
70
|
+
@concept_manager.path = path
|
71
|
+
@concept_manager.load_from_files(collection: self)
|
72
|
+
end
|
73
|
+
|
74
|
+
def save_to_files(path)
|
75
|
+
@concept_manager.path = path
|
76
|
+
@concept_manager.save_to_files(@managed_concepts)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (c) Copyright 2021 Ribose Inc.
|
4
|
+
#
|
5
|
+
|
6
|
+
module Glossarist
|
7
|
+
class Model
|
8
|
+
def self.new(params = {})
|
9
|
+
return params if params.is_a?(self)
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(attributes = {})
|
15
|
+
attributes.each_pair { |k, v| set_attribute(k, v) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_attribute(name, value)
|
19
|
+
public_send("#{name}=", value)
|
20
|
+
rescue NoMethodError
|
21
|
+
raise ArgumentError, "#{self.class.name} does not have " +
|
22
|
+
"attribute #{name} defined or the attribute is read only."
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_h(hash)
|
26
|
+
new(hash)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glossarist
|
4
|
+
class NonVerbRep
|
5
|
+
attr_accessor :image
|
6
|
+
attr_accessor :table
|
7
|
+
attr_accessor :formula
|
8
|
+
|
9
|
+
# @return [Array<ConceptSource>]
|
10
|
+
attr_reader :sources
|
11
|
+
|
12
|
+
def sources=(sources)
|
13
|
+
@sources = sources&.map do |source|
|
14
|
+
ConceptSource.new(source)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|