unitsml 0.6.3 → 0.6.4
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/Gemfile +5 -2
- data/docs/README.adoc +16 -2
- data/lib/unitsml/configuration.rb +47 -0
- data/lib/unitsml/dimension.rb +10 -4
- data/lib/unitsml/errors/opal_payload_not_bundled_error.rb +11 -0
- data/lib/unitsml/errors.rb +2 -0
- data/lib/unitsml/extender.rb +3 -1
- data/lib/unitsml/fenced.rb +6 -2
- data/lib/unitsml/formula.rb +14 -18
- data/lib/unitsml/mathml_helper.rb +60 -0
- data/lib/unitsml/number.rb +5 -3
- data/lib/unitsml/prefix.rb +3 -1
- data/lib/unitsml/unit.rb +10 -16
- data/lib/unitsml/unitsdb/database.rb +22 -0
- data/lib/unitsml/unitsdb/dimension.rb +23 -20
- data/lib/unitsml/unitsdb/{dimension_quantity.rb → dimension_details.rb} +3 -1
- data/lib/unitsml/unitsdb/dimensions.rb +2 -0
- data/lib/unitsml/unitsdb/prefix_reference.rb +3 -1
- data/lib/unitsml/unitsdb/prefixes.rb +2 -0
- data/lib/unitsml/unitsdb/quantities.rb +2 -0
- data/lib/unitsml/unitsdb/unit.rb +2 -8
- data/lib/unitsml/unitsdb/units.rb +2 -4
- data/lib/unitsml/unitsdb.rb +82 -14
- data/lib/unitsml/utility.rb +160 -35
- data/lib/unitsml/version.rb +1 -1
- data/lib/unitsml.rb +3 -44
- data/unitsml.gemspec +2 -2
- metadata +11 -8
- data/lib/unitsml/unitsdb/si_derived_base.rb +0 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 70a152434290d3e4f3274a3b5beed15db5d0e6184c93b629363311b8dcc39579
|
|
4
|
+
data.tar.gz: d70bd8514fafbfec08624c17f11440aa4277f57c0d6d045a39c8611f70952c56
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b18a3a711ca1f5fb60a59283ec4d62d976cd0e0ad30fd199ca0c17327fdad398b1b345d76f8e08d57bdee4f2ea2d9ab36accf9016e647214b640a564f938f0a8
|
|
7
|
+
data.tar.gz: 6e8c2bcb409905222668fdf87e2470df42d3fde887dcf065d085111b588995529648fd296ef0b2da9040fc040bc2ffb8045f1e940d1dba5d1e99ac8ff156ab8b
|
data/Gemfile
CHANGED
|
@@ -6,10 +6,13 @@ source "https://rubygems.org"
|
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
8
|
gem "canon"
|
|
9
|
-
gem "lutaml-model",
|
|
9
|
+
gem "lutaml-model",
|
|
10
|
+
github: "lutaml/lutaml-model",
|
|
11
|
+
branch: "fix/global-context-register-lookup-fallback"
|
|
10
12
|
gem "oga"
|
|
11
13
|
gem "ox"
|
|
12
|
-
gem "plurimath", github: "plurimath/plurimath",
|
|
14
|
+
gem "plurimath", github: "plurimath/plurimath",
|
|
15
|
+
branch: "rt-lutaml-080"
|
|
13
16
|
gem "pry"
|
|
14
17
|
gem "rake"
|
|
15
18
|
gem "rspec"
|
data/docs/README.adoc
CHANGED
|
@@ -40,8 +40,22 @@ The UnitsML Ruby library consists of several key components:
|
|
|
40
40
|
* Prefix: Represents unit prefixes (k, m, μ, etc.)
|
|
41
41
|
* Dimension: Represents physical dimensions
|
|
42
42
|
|
|
43
|
-
The library
|
|
44
|
-
|
|
43
|
+
The library uses the https://github.com/unitsml/unitsdb-ruby[unitsdb-ruby]
|
|
44
|
+
gem as the primary runtime source for standard units, prefixes, and dimensions.
|
|
45
|
+
|
|
46
|
+
== Development setup
|
|
47
|
+
|
|
48
|
+
The development `Gemfile` pins the current integration branches for
|
|
49
|
+
`lutaml-model`, `mml`, `plurimath`, and `unitsdb-ruby`. If you need to test
|
|
50
|
+
coordinated local changes across those repositories, temporarily switch those
|
|
51
|
+
dependencies to Bundler `path` entries that point at sibling checkouts, for
|
|
52
|
+
example `../lutaml-model` or `../unitsdb-ruby`. Keep those local path changes
|
|
53
|
+
out of commits unless the branch intentionally requires them.
|
|
54
|
+
|
|
55
|
+
The standard Ruby runtime path goes through `::Unitsdb.database`. When
|
|
56
|
+
`unitsdb-ruby` cannot load its bundled `data/` directory, UnitsML falls back to
|
|
57
|
+
the packaged YAML files in the `unitsdb-ruby` gem's `vendor/unitsdb`
|
|
58
|
+
directory, rather than a `vendor/unitsdb` directory in this repository.
|
|
45
59
|
|
|
46
60
|
|
|
47
61
|
== Usage
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "unitsdb"
|
|
4
|
+
|
|
5
|
+
module Unitsml
|
|
6
|
+
module Configuration
|
|
7
|
+
CONTEXT_ID = :unitsml_ruby
|
|
8
|
+
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def context_id
|
|
12
|
+
CONTEXT_ID
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def context(force_populate: false)
|
|
16
|
+
existing = ::Unitsdb::Config.find_context(context_id)
|
|
17
|
+
return existing if existing && !force_populate
|
|
18
|
+
|
|
19
|
+
build_context
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def register_model(klass, id:)
|
|
23
|
+
registered_models[id.to_sym] = klass
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def registered_models
|
|
27
|
+
@registered_models ||= {}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def build_context
|
|
31
|
+
::Unitsdb::Config.context # ensure unitsdb context exists
|
|
32
|
+
|
|
33
|
+
substitutions = registered_models.each_value.filter_map do |klass|
|
|
34
|
+
parent = klass.superclass
|
|
35
|
+
next if parent == Object
|
|
36
|
+
|
|
37
|
+
{ from_type: parent, to_type: klass }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
::Unitsdb::Config.populate_context(
|
|
41
|
+
id: context_id,
|
|
42
|
+
fallback_to: [::Unitsdb::Config.context_id],
|
|
43
|
+
substitutions: substitutions,
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/unitsml/dimension.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
class Dimension
|
|
5
|
+
include MathmlHelper
|
|
6
|
+
|
|
5
7
|
attr_accessor :dimension_name, :power_numerator
|
|
6
8
|
|
|
7
9
|
def initialize(dimension_name, power_numerator = nil)
|
|
@@ -26,7 +28,7 @@ module Unitsml
|
|
|
26
28
|
def to_mathml(options)
|
|
27
29
|
# MathML key's value in unitsdb/dimensions.yaml
|
|
28
30
|
# file includes mi tags only.
|
|
29
|
-
value =
|
|
31
|
+
value = mml_v4_from_xml(:mi, dim_symbols.mathml)
|
|
30
32
|
method_name = if power_numerator
|
|
31
33
|
value = msup_tag(value, options)
|
|
32
34
|
:msup
|
|
@@ -63,7 +65,10 @@ module Unitsml
|
|
|
63
65
|
symbol: dim_instance.processed_symbol,
|
|
64
66
|
power_numerator: power_numerator&.raw_value || 1,
|
|
65
67
|
}
|
|
66
|
-
Model::DimensionQuantities.const_get(modelize(element_name)).new(
|
|
68
|
+
Model::DimensionQuantities.const_get(modelize(element_name)).new(
|
|
69
|
+
**attributes,
|
|
70
|
+
lutaml_register: Configuration.context.id,
|
|
71
|
+
)
|
|
67
72
|
end
|
|
68
73
|
|
|
69
74
|
def xml_instances_hash(options)
|
|
@@ -94,8 +99,9 @@ module Unitsml
|
|
|
94
99
|
|
|
95
100
|
def msup_tag(value, options)
|
|
96
101
|
mathml = power_numerator.to_mathml(options)
|
|
97
|
-
msup =
|
|
98
|
-
|
|
102
|
+
msup = mml_v4_new(
|
|
103
|
+
:msup,
|
|
104
|
+
mrow_value: [mml_v4_new(:mrow, mi_value: [value])],
|
|
99
105
|
)
|
|
100
106
|
[mathml].flatten.each do |record|
|
|
101
107
|
record_values = msup.public_send("#{record[:method_name]}_value") || []
|
data/lib/unitsml/errors.rb
CHANGED
data/lib/unitsml/extender.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
class Extender
|
|
5
|
+
include MathmlHelper
|
|
6
|
+
|
|
5
7
|
attr_accessor :symbol
|
|
6
8
|
|
|
7
9
|
def initialize(symbol)
|
|
@@ -18,7 +20,7 @@ module Unitsml
|
|
|
18
20
|
extender = multiplier(options[:multiplier] || "⋅", unicode: true)
|
|
19
21
|
{
|
|
20
22
|
method_name: :mo,
|
|
21
|
-
value:
|
|
23
|
+
value: mml_v4_new(:mo, value: extender, rspace: rspace),
|
|
22
24
|
}
|
|
23
25
|
end
|
|
24
26
|
|
data/lib/unitsml/fenced.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
class Fenced
|
|
5
5
|
include FencedNumeric
|
|
6
|
+
include MathmlHelper
|
|
6
7
|
|
|
7
8
|
attr_reader :open_paren, :value, :close_paren
|
|
8
9
|
|
|
@@ -31,11 +32,14 @@ module Unitsml
|
|
|
31
32
|
mathml = value.to_mathml(options)
|
|
32
33
|
return mathml unless options[:explicit_parenthesis]
|
|
33
34
|
|
|
34
|
-
fenced =
|
|
35
|
+
fenced = mml_v4_new(
|
|
36
|
+
:mrow,
|
|
37
|
+
mo_value: [mml_v4_new(:mo, value: open_paren)],
|
|
38
|
+
)
|
|
35
39
|
fenced.ordered = true
|
|
36
40
|
fenced.element_order ||= [xml_order_element("mo")]
|
|
37
41
|
[mathml].flatten.each { |record| add_math_element(fenced, record) }
|
|
38
|
-
fenced.mo_value <<
|
|
42
|
+
fenced.mo_value << mml_v4_new(:mo, value: close_paren)
|
|
39
43
|
fenced.element_order << xml_order_element("mo")
|
|
40
44
|
{ method_name: :mrow, value: fenced }
|
|
41
45
|
end
|
data/lib/unitsml/formula.rb
CHANGED
|
@@ -5,6 +5,8 @@ require "htmlentities"
|
|
|
5
5
|
|
|
6
6
|
module Unitsml
|
|
7
7
|
class Formula
|
|
8
|
+
include MathmlHelper
|
|
9
|
+
|
|
8
10
|
attr_accessor :value, :explicit_value, :root
|
|
9
11
|
|
|
10
12
|
def initialize(value = [],
|
|
@@ -29,15 +31,14 @@ module Unitsml
|
|
|
29
31
|
def to_mathml(options = {})
|
|
30
32
|
if root
|
|
31
33
|
options = update_options(options)
|
|
32
|
-
|
|
33
|
-
math = ::Mml::V4::Math.new(display: "block")
|
|
34
|
+
math = mml_v4_new(:math, display: "block")
|
|
34
35
|
math.ordered = true
|
|
35
36
|
math.element_order ||= []
|
|
36
37
|
value.each do |instance|
|
|
37
38
|
process_value(math, instance.to_mathml(options))
|
|
38
39
|
end
|
|
39
|
-
generated_math = math.to_xml
|
|
40
|
-
|
|
40
|
+
generated_math = math.to_xml(register: mml_v4_context.id)
|
|
41
|
+
.gsub(%r{&(.*?)(?=</)}, '&\1')
|
|
41
42
|
|
|
42
43
|
generated_math.force_encoding("UTF-8")
|
|
43
44
|
else
|
|
@@ -80,7 +81,7 @@ module Unitsml
|
|
|
80
81
|
:asciimath)
|
|
81
82
|
end
|
|
82
83
|
|
|
83
|
-
Plurimath::Math.parse(to_mathml(options), :mathml)
|
|
84
|
+
Plurimath::Math.parse(compact_mathml_for_plurimath(to_mathml(options)), :mathml)
|
|
84
85
|
end
|
|
85
86
|
|
|
86
87
|
def dimensions_extraction
|
|
@@ -151,7 +152,10 @@ module Unitsml
|
|
|
151
152
|
dim_id = dims.map(&:generate_id).join
|
|
152
153
|
attributes = { id: "D_#{dim_id}" }
|
|
153
154
|
dims.each { |dim| attributes.merge!(dim.xml_instances_hash(options)) }
|
|
154
|
-
Model::Dimension.new(
|
|
155
|
+
Model::Dimension.new(
|
|
156
|
+
**attributes,
|
|
157
|
+
lutaml_register: Configuration.context.id,
|
|
158
|
+
).to_xml.force_encoding("UTF-8")
|
|
155
159
|
end
|
|
156
160
|
|
|
157
161
|
def sort_dims(values)
|
|
@@ -195,18 +199,6 @@ module Unitsml
|
|
|
195
199
|
Plurimath.const_defined?(:Mathml)
|
|
196
200
|
end
|
|
197
201
|
|
|
198
|
-
def nullify_mml_models
|
|
199
|
-
return unless defined?(Plurimath::Mathml::Parser::CONFIGURATION)
|
|
200
|
-
|
|
201
|
-
Plurimath::Mathml::Parser::CONFIGURATION.each_key { |klass| klass.model(klass) }
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
def reset_mml_models
|
|
205
|
-
return unless defined?(Plurimath::Mathml::Parser::CONFIGURATION)
|
|
206
|
-
|
|
207
|
-
::Mml::V4::Configuration.custom_models = Plurimath::Mathml::Parser::CONFIGURATION
|
|
208
|
-
end
|
|
209
|
-
|
|
210
202
|
def process_value(math, mathml_instances)
|
|
211
203
|
case mathml_instances
|
|
212
204
|
when Array
|
|
@@ -224,5 +216,9 @@ module Unitsml
|
|
|
224
216
|
options.merge(multiplier: multiplier,
|
|
225
217
|
explicit_parenthesis: explicit_parenthesis).compact
|
|
226
218
|
end
|
|
219
|
+
|
|
220
|
+
def compact_mathml_for_plurimath(mathml)
|
|
221
|
+
mathml.gsub(/>\s+</, "><").strip
|
|
222
|
+
end
|
|
227
223
|
end
|
|
228
224
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unitsml
|
|
4
|
+
module MathmlHelper
|
|
5
|
+
module_function
|
|
6
|
+
|
|
7
|
+
def mml_v4_context
|
|
8
|
+
::Mml::V4::Configuration.context
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def mml_v4_from_xml(klass_ref, xml)
|
|
12
|
+
mml_v4_class_for(klass_ref).from_xml(xml, register: mml_v4_context.id)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def mml_v4_new(klass_ref, **attributes)
|
|
16
|
+
klass = mml_v4_class_for(klass_ref)
|
|
17
|
+
coerce_mml_v4_collection_attributes!(klass, attributes)
|
|
18
|
+
klass.new(**attributes, lutaml_register: mml_v4_context.id)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def mml_v4_with_content(instance, content)
|
|
22
|
+
attributes = instance.to_hash.transform_keys(&:to_sym)
|
|
23
|
+
mml_v4_new(
|
|
24
|
+
instance.class,
|
|
25
|
+
**attributes,
|
|
26
|
+
mml_v4_content_attribute(instance) => content,
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def mml_v4_class_for(klass_ref)
|
|
31
|
+
return klass_ref if klass_ref.is_a?(Class)
|
|
32
|
+
|
|
33
|
+
mml_v4_context.lookup_local(klass_ref.to_sym)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def coerce_mml_v4_collection_attributes!(klass, attributes)
|
|
39
|
+
return unless klass.respond_to?(:attributes)
|
|
40
|
+
|
|
41
|
+
attributes.each do |name, value|
|
|
42
|
+
attribute = klass.attributes[name]
|
|
43
|
+
attributes[name] = coerce_mml_v4_collection_value(attribute, value)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def coerce_mml_v4_collection_value(attribute, value)
|
|
48
|
+
return value unless attribute&.collection?
|
|
49
|
+
return value if value.nil?
|
|
50
|
+
return value if attribute.collection_instance?(value)
|
|
51
|
+
|
|
52
|
+
attribute.build_collection(value)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def mml_v4_content_attribute(instance)
|
|
56
|
+
register = instance.lutaml_register || mml_v4_context.id
|
|
57
|
+
instance.class.mappings_for(:xml, register).content_mapping.to
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
data/lib/unitsml/number.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
class Number
|
|
5
5
|
include FencedNumeric
|
|
6
|
+
include MathmlHelper
|
|
6
7
|
|
|
7
8
|
attr_accessor :value
|
|
8
9
|
alias raw_value value
|
|
@@ -19,7 +20,7 @@ module Unitsml
|
|
|
19
20
|
def to_mathml(_options)
|
|
20
21
|
matched_value = value&.match(/-?(.+)/)
|
|
21
22
|
mn_value = matched_value ? matched_value[1] : value
|
|
22
|
-
mn_tag =
|
|
23
|
+
mn_tag = mml_v4_new(:mn, value: mn_value)
|
|
23
24
|
value.start_with?("-") ? mrow_hash(mn_tag) : mn_hash(mn_tag)
|
|
24
25
|
end
|
|
25
26
|
|
|
@@ -62,8 +63,9 @@ module Unitsml
|
|
|
62
63
|
def mrow_hash(mn_tag)
|
|
63
64
|
{
|
|
64
65
|
method_name: :mrow,
|
|
65
|
-
value:
|
|
66
|
-
|
|
66
|
+
value: mml_v4_new(
|
|
67
|
+
:mrow,
|
|
68
|
+
mo_value: [mml_v4_new(:mo, value: "−")],
|
|
67
69
|
mn_value: [mn_tag],
|
|
68
70
|
),
|
|
69
71
|
}
|
data/lib/unitsml/prefix.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
class Prefix
|
|
5
|
+
include MathmlHelper
|
|
6
|
+
|
|
5
7
|
attr_accessor :prefix_name, :only_instance
|
|
6
8
|
|
|
7
9
|
def initialize(prefix_name, only_instance = false)
|
|
@@ -41,7 +43,7 @@ module Unitsml
|
|
|
41
43
|
)
|
|
42
44
|
return symbol unless only_instance
|
|
43
45
|
|
|
44
|
-
{ method_name: :mi, value:
|
|
46
|
+
{ method_name: :mi, value: mml_v4_new(:mi, value: symbol) }
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
def to_latex(_)
|
data/lib/unitsml/unit.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
class Unit
|
|
5
|
+
include MathmlHelper
|
|
6
|
+
|
|
5
7
|
attr_accessor :unit_name, :power_numerator, :prefix
|
|
6
8
|
|
|
7
9
|
SI_UNIT_SYSTEM = %w[si_base si_derived_special
|
|
@@ -35,13 +37,14 @@ module Unitsml
|
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
def to_mathml(options)
|
|
38
|
-
|
|
39
|
-
tag_name =
|
|
40
|
-
|
|
41
|
-
value = klass.from_xml(raw_mathml)
|
|
40
|
+
value = unit_symbols&.mathml
|
|
41
|
+
tag_name = value.match(/^<(?<tag>\w+)/)[:tag]
|
|
42
|
+
value = mml_v4_from_xml(tag_name, value)
|
|
42
43
|
if prefix
|
|
43
|
-
value =
|
|
44
|
-
|
|
44
|
+
value = mml_v4_with_content(
|
|
45
|
+
value,
|
|
46
|
+
"#{prefix.to_mathml(options.merge(parent: value))}#{Array(value.value).join}",
|
|
47
|
+
)
|
|
45
48
|
end
|
|
46
49
|
if power_numerator
|
|
47
50
|
value = msup_tag(
|
|
@@ -130,17 +133,8 @@ module Unitsml
|
|
|
130
133
|
unit_instance.unit_system_reference
|
|
131
134
|
end
|
|
132
135
|
|
|
133
|
-
def with_updated_value(element, new_value)
|
|
134
|
-
attrs = element.class.attributes.each_with_object({}) do |(name, _), h|
|
|
135
|
-
val = element.public_send(name)
|
|
136
|
-
h[name] = val unless val.nil?
|
|
137
|
-
end
|
|
138
|
-
attrs[:value] = new_value
|
|
139
|
-
element.class.new(**attrs)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
136
|
def msup_tag(value, options)
|
|
143
|
-
msup =
|
|
137
|
+
msup = mml_v4_new(:msup)
|
|
144
138
|
msup.ordered = true
|
|
145
139
|
msup.element_order = []
|
|
146
140
|
[value, power_numerator.to_mathml(options)].flatten.each do |record|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unitsml
|
|
4
|
+
module Unitsdb
|
|
5
|
+
class Database < ::Unitsdb::Database
|
|
6
|
+
DATABASE = nil
|
|
7
|
+
|
|
8
|
+
def self.from_db(dir_path, context: Unitsml::Configuration.context.id)
|
|
9
|
+
return super unless RUBY_ENGINE == "opal"
|
|
10
|
+
|
|
11
|
+
context_id = context.to_sym
|
|
12
|
+
raise Unitsml::Errors::OpalPayloadNotBundledError unless DATABASE
|
|
13
|
+
|
|
14
|
+
Unitsml::Configuration.context
|
|
15
|
+
|
|
16
|
+
from_hash(DATABASE, register: context_id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
Configuration.register_model(self, id: :database)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -16,43 +16,41 @@ module Unitsml
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def length=(value)
|
|
19
|
-
quantities_common_code(:length,
|
|
19
|
+
quantities_common_code(:length, value)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def mass=(value)
|
|
23
|
-
quantities_common_code(:mass,
|
|
23
|
+
quantities_common_code(:mass, value)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def time=(value)
|
|
27
|
-
quantities_common_code(:time,
|
|
27
|
+
quantities_common_code(:time, value)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def thermodynamic_temperature=(value)
|
|
31
|
-
quantities_common_code(:thermodynamic_temperature,
|
|
32
|
-
wrap_dimension_value(value))
|
|
31
|
+
quantities_common_code(:thermodynamic_temperature, value)
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
def amount_of_substance=(value)
|
|
36
|
-
quantities_common_code(:amount_of_substance,
|
|
37
|
-
wrap_dimension_value(value))
|
|
35
|
+
quantities_common_code(:amount_of_substance, value)
|
|
38
36
|
end
|
|
39
37
|
|
|
40
38
|
def luminous_intensity=(value)
|
|
41
|
-
quantities_common_code(:luminous_intensity,
|
|
39
|
+
quantities_common_code(:luminous_intensity, value)
|
|
42
40
|
end
|
|
43
41
|
|
|
44
42
|
def plane_angle=(value)
|
|
45
|
-
quantities_common_code(:plane_angle,
|
|
43
|
+
quantities_common_code(:plane_angle, value)
|
|
46
44
|
end
|
|
47
45
|
|
|
48
46
|
def electric_current=(value)
|
|
49
|
-
quantities_common_code(:electric_current,
|
|
47
|
+
quantities_common_code(:electric_current, value)
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
def dim_symbols
|
|
53
|
-
processed_keys.
|
|
54
|
-
public_send(vec)
|
|
55
|
-
end.
|
|
51
|
+
processed_keys.flat_map do |vec|
|
|
52
|
+
dimension_symbols_for(public_send(vec)).map(&:id)
|
|
53
|
+
end.compact
|
|
56
54
|
end
|
|
57
55
|
|
|
58
56
|
def processed_symbol
|
|
@@ -76,19 +74,24 @@ module Unitsml
|
|
|
76
74
|
|
|
77
75
|
instance_variable_set(:"@#{instance_var}", value)
|
|
78
76
|
@processed_keys << instance_var.to_s
|
|
79
|
-
|
|
77
|
+
dim_symbols = dimension_symbols_for(value)
|
|
78
|
+
return if Lutaml::Model::Utils.empty?(dim_symbols)
|
|
80
79
|
|
|
81
80
|
@parsable = true
|
|
82
|
-
|
|
81
|
+
dim_symbols.each { |dim_sym| @parsables[dim_sym.id] = id }
|
|
83
82
|
end
|
|
84
83
|
|
|
85
|
-
def
|
|
86
|
-
return
|
|
87
|
-
return DimensionQuantity.new(value.to_hash) if value.is_a?(::Unitsdb::DimensionDetails)
|
|
88
|
-
return DimensionQuantity.new(value) if value.is_a?(Hash)
|
|
84
|
+
def dimension_symbols_for(value)
|
|
85
|
+
return [] if value.nil?
|
|
89
86
|
|
|
90
|
-
value
|
|
87
|
+
if value.respond_to?(:dim_symbols)
|
|
88
|
+
Array(value.dim_symbols)
|
|
89
|
+
else
|
|
90
|
+
Array(value.symbols)
|
|
91
|
+
end
|
|
91
92
|
end
|
|
92
93
|
end
|
|
94
|
+
|
|
95
|
+
Configuration.register_model(Dimension, id: :dimension)
|
|
93
96
|
end
|
|
94
97
|
end
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
module Unitsdb
|
|
5
|
-
class
|
|
5
|
+
class DimensionDetails < ::Unitsdb::DimensionDetails
|
|
6
6
|
def dim_symbols_ids(hash, dim_id)
|
|
7
7
|
symbols&.each { |dim_sym| hash[dim_sym.id] = dim_id }
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
Configuration.register_model(DimensionDetails, id: :dimension_details)
|
|
10
12
|
end
|
|
11
13
|
end
|
|
@@ -16,10 +16,12 @@ module Unitsml
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def prefix
|
|
19
|
-
@prefix ||= ::Unitsdb.database.prefixes.find do |p|
|
|
19
|
+
@prefix ||= Unitsml::Unitsdb.database.prefixes.find do |p|
|
|
20
20
|
p.identifiers.any? { |i| i.id == id }
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
+
|
|
25
|
+
Configuration.register_model(PrefixReference, id: :prefix_reference)
|
|
24
26
|
end
|
|
25
27
|
end
|
data/lib/unitsml/unitsdb/unit.rb
CHANGED
|
@@ -3,14 +3,6 @@
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
module Unitsdb
|
|
5
5
|
class Unit < ::Unitsdb::Unit
|
|
6
|
-
def si_derived_bases=(value)
|
|
7
|
-
return super if value.nil?
|
|
8
|
-
|
|
9
|
-
super(value.map do |s|
|
|
10
|
-
SiDerivedBase.new(s.to_hash)
|
|
11
|
-
end)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
6
|
def dimension_url
|
|
15
7
|
quantity_id = quantity_references[0].id
|
|
16
8
|
quantity = Unitsml::Unitsdb.quantities.find_by_id(quantity_id)
|
|
@@ -24,6 +16,8 @@ module Unitsml
|
|
|
24
16
|
def nist_id
|
|
25
17
|
identifiers.find { |id| id.type == "nist" }&.id
|
|
26
18
|
end
|
|
19
|
+
|
|
20
|
+
Configuration.register_model(self, id: :unit)
|
|
27
21
|
end
|
|
28
22
|
end
|
|
29
23
|
end
|
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
module Unitsdb
|
|
5
5
|
class Units < ::Unitsdb::Units
|
|
6
|
-
def units=(value)
|
|
7
|
-
super(value.map { |u| Unit.new(u.to_hash) })
|
|
8
|
-
end
|
|
9
|
-
|
|
10
6
|
def find_by_id(u_id)
|
|
11
7
|
find(u_id, :id, :identifiers)
|
|
12
8
|
end
|
|
@@ -45,5 +41,7 @@ module Unitsml
|
|
|
45
41
|
end
|
|
46
42
|
end
|
|
47
43
|
end
|
|
44
|
+
|
|
45
|
+
Configuration.register_model(Units, id: :units)
|
|
48
46
|
end
|
|
49
47
|
end
|
data/lib/unitsml/unitsdb.rb
CHANGED
|
@@ -1,32 +1,53 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "unitsdb"
|
|
4
|
+
|
|
5
|
+
require_relative "unitsdb/database"
|
|
6
|
+
require_relative "unitsdb/dimension_details"
|
|
7
|
+
require_relative "unitsdb/prefix_reference"
|
|
8
|
+
require_relative "unitsdb/dimension"
|
|
9
|
+
require_relative "unitsdb/dimensions"
|
|
10
|
+
require_relative "unitsdb/unit"
|
|
11
|
+
require_relative "unitsdb/units"
|
|
12
|
+
require_relative "unitsdb/prefixes"
|
|
13
|
+
require_relative "unitsdb/quantities"
|
|
3
14
|
module Unitsml
|
|
4
15
|
module Unitsdb
|
|
5
|
-
autoload :Unit, "#{__dir__}/unitsdb/unit"
|
|
6
|
-
autoload :Units, "#{__dir__}/unitsdb/units"
|
|
7
|
-
autoload :Prefixes, "#{__dir__}/unitsdb/prefixes"
|
|
8
|
-
autoload :Dimension, "#{__dir__}/unitsdb/dimension"
|
|
9
|
-
autoload :Dimensions, "#{__dir__}/unitsdb/dimensions"
|
|
10
|
-
autoload :Quantities, "#{__dir__}/unitsdb/quantities"
|
|
11
|
-
autoload :PrefixReference, "#{__dir__}/unitsdb/prefix_reference"
|
|
12
|
-
autoload :DimensionQuantity, "#{__dir__}/unitsdb/dimension_quantity"
|
|
13
|
-
autoload :SiDerivedBase, "#{__dir__}/unitsdb/si_derived_base"
|
|
14
|
-
|
|
15
16
|
class << self
|
|
17
|
+
REQUIRED_DATABASE_FILES = %w[
|
|
18
|
+
prefixes.yaml
|
|
19
|
+
dimensions.yaml
|
|
20
|
+
units.yaml
|
|
21
|
+
quantities.yaml
|
|
22
|
+
unit_systems.yaml
|
|
23
|
+
].freeze
|
|
24
|
+
|
|
16
25
|
def units
|
|
17
|
-
Units.new(
|
|
26
|
+
@units ||= Units.new(
|
|
27
|
+
units: database.units,
|
|
28
|
+
lutaml_register: Configuration.context.id,
|
|
29
|
+
)
|
|
18
30
|
end
|
|
19
31
|
|
|
20
32
|
def prefixes
|
|
21
|
-
Prefixes.new(
|
|
33
|
+
@prefixes ||= Prefixes.new(
|
|
34
|
+
prefixes: database.prefixes,
|
|
35
|
+
lutaml_register: Configuration.context.id,
|
|
36
|
+
)
|
|
22
37
|
end
|
|
23
38
|
|
|
24
39
|
def dimensions
|
|
25
|
-
Dimensions.new(
|
|
40
|
+
@dimensions ||= Dimensions.new(
|
|
41
|
+
dimensions: database.dimensions,
|
|
42
|
+
lutaml_register: Configuration.context.id,
|
|
43
|
+
)
|
|
26
44
|
end
|
|
27
45
|
|
|
28
46
|
def quantities
|
|
29
|
-
Quantities.new(
|
|
47
|
+
@quantities ||= Quantities.new(
|
|
48
|
+
quantities: database.quantities,
|
|
49
|
+
lutaml_register: Configuration.context.id,
|
|
50
|
+
)
|
|
30
51
|
end
|
|
31
52
|
|
|
32
53
|
def prefixes_array
|
|
@@ -39,6 +60,53 @@ module Unitsml
|
|
|
39
60
|
|
|
40
61
|
@sized_prefixes[size] = prefixes_array.select { |p| p.size == size }
|
|
41
62
|
end
|
|
63
|
+
|
|
64
|
+
def database
|
|
65
|
+
@database ||= load_database
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def load_database
|
|
71
|
+
context_id = Configuration.context.id
|
|
72
|
+
|
|
73
|
+
if ::Unitsdb.respond_to?(:database)
|
|
74
|
+
return load_unitsdb_database(context_id)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
Database.from_db(database_path, context: context_id)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def load_unitsdb_database(context_id)
|
|
81
|
+
::Unitsdb.database(context: context_id)
|
|
82
|
+
rescue ::Unitsdb::Errors::DatabaseNotFoundError,
|
|
83
|
+
::Unitsdb::Errors::DatabaseFileNotFoundError
|
|
84
|
+
Database.from_db(database_path, context: context_id)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def database_path
|
|
88
|
+
candidate_database_paths.find do |path|
|
|
89
|
+
database_files_present?(path)
|
|
90
|
+
end ||
|
|
91
|
+
File.join(unitsdb_gem_path, "vendor", "unitsdb")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def candidate_database_paths
|
|
95
|
+
[
|
|
96
|
+
File.join(unitsdb_gem_path, "data"),
|
|
97
|
+
File.join(unitsdb_gem_path, "vendor", "unitsdb"),
|
|
98
|
+
]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def database_files_present?(dir_path)
|
|
102
|
+
REQUIRED_DATABASE_FILES.all? do |file_name|
|
|
103
|
+
File.exist?(File.join(dir_path, file_name))
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def unitsdb_gem_path
|
|
108
|
+
Gem.loaded_specs.fetch("unitsdb").full_gem_path
|
|
109
|
+
end
|
|
42
110
|
end
|
|
43
111
|
end
|
|
44
112
|
end
|
data/lib/unitsml/utility.rb
CHANGED
|
@@ -40,6 +40,12 @@ module Unitsml
|
|
|
40
40
|
].freeze
|
|
41
41
|
|
|
42
42
|
UNKNOWN = "unknown"
|
|
43
|
+
PREFIX_SYMBOL_METHODS = {
|
|
44
|
+
ASCII: :to_asciimath,
|
|
45
|
+
unicode: :to_unicode,
|
|
46
|
+
LaTeX: :to_latex,
|
|
47
|
+
HTML: :to_html,
|
|
48
|
+
}.freeze
|
|
43
49
|
|
|
44
50
|
class << self
|
|
45
51
|
def unit_instance(unit)
|
|
@@ -139,26 +145,71 @@ module Unitsml
|
|
|
139
145
|
end
|
|
140
146
|
|
|
141
147
|
def prefix_object(prefix)
|
|
142
|
-
return
|
|
143
|
-
return
|
|
148
|
+
return nil if prefix.nil?
|
|
149
|
+
return prefix if prefix_like?(prefix)
|
|
150
|
+
|
|
151
|
+
if prefix.is_a?(String)
|
|
152
|
+
return nil unless Unitsdb.prefixes_array.any?(prefix)
|
|
153
|
+
|
|
154
|
+
return Prefix.new(prefix)
|
|
155
|
+
end
|
|
144
156
|
|
|
145
|
-
|
|
157
|
+
return Unitsdb.prefixes.find_by_id(prefix.id) if prefix.respond_to?(:id)
|
|
158
|
+
|
|
159
|
+
prefix
|
|
146
160
|
end
|
|
147
161
|
|
|
148
162
|
def combine_prefixes(p1, p2)
|
|
163
|
+
p1 = prefix_object(p1)
|
|
164
|
+
p2 = prefix_object(p2)
|
|
149
165
|
return nil if p1.nil? && p2.nil?
|
|
150
|
-
return p1
|
|
151
|
-
return p2
|
|
152
|
-
return UNKNOWN if p1
|
|
166
|
+
return prefix_symbolid(p1) if p2.nil?
|
|
167
|
+
return prefix_symbolid(p2) if p1.nil?
|
|
168
|
+
return UNKNOWN if prefix_base(p1) != prefix_base(p2)
|
|
153
169
|
|
|
154
170
|
Unitsdb.prefixes_array.each do |prefix_name|
|
|
155
171
|
p = prefix_object(prefix_name)
|
|
156
|
-
return p if p
|
|
172
|
+
return p if prefix_base(p) == prefix_base(p1) &&
|
|
173
|
+
prefix_power(p) == prefix_power(p1) + prefix_power(p2)
|
|
157
174
|
end
|
|
158
175
|
|
|
159
176
|
UNKNOWN
|
|
160
177
|
end
|
|
161
178
|
|
|
179
|
+
def prefix_like?(prefix)
|
|
180
|
+
prefix.respond_to?(:base) && prefix.respond_to?(:power) &&
|
|
181
|
+
(prefix.respond_to?(:symbolid) || prefix.respond_to?(:symbols))
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def prefix_symbolid(prefix)
|
|
185
|
+
return prefix.symbolid if prefix.respond_to?(:symbolid)
|
|
186
|
+
|
|
187
|
+
prefix_record = resolved_prefix(prefix)
|
|
188
|
+
return unless prefix_record
|
|
189
|
+
|
|
190
|
+
prefix_record.symbols&.first&.ascii
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def prefix_base(prefix)
|
|
194
|
+
return prefix.base if prefix.respond_to?(:base)
|
|
195
|
+
|
|
196
|
+
resolved_prefix(prefix)&.base
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def prefix_power(prefix)
|
|
200
|
+
return prefix.power if prefix.respond_to?(:power)
|
|
201
|
+
|
|
202
|
+
resolved_prefix(prefix)&.power
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def resolved_prefix(prefix)
|
|
206
|
+
return prefix if prefix.nil?
|
|
207
|
+
return prefix if prefix.respond_to?(:symbols) && prefix.respond_to?(:base) && prefix.respond_to?(:power)
|
|
208
|
+
return Unitsdb.prefixes.find_by_id(prefix.id) if prefix.respond_to?(:id)
|
|
209
|
+
|
|
210
|
+
prefix
|
|
211
|
+
end
|
|
212
|
+
|
|
162
213
|
def unit(units, formula, dims, norm_text, name, options)
|
|
163
214
|
attributes = {
|
|
164
215
|
id: unit_id(norm_text),
|
|
@@ -168,7 +219,7 @@ module Unitsml
|
|
|
168
219
|
root_units: rootunits(units),
|
|
169
220
|
}
|
|
170
221
|
attributes[:dimension_url] = "##{dim_id(dims)}" if dims
|
|
171
|
-
Model::Unit.new(attributes).to_xml
|
|
222
|
+
Model::Unit.new(**attributes, lutaml_register: Configuration.context.id).to_xml
|
|
172
223
|
.force_encoding("UTF-8")
|
|
173
224
|
.gsub("<", "<")
|
|
174
225
|
.gsub(">", ">")
|
|
@@ -178,8 +229,11 @@ module Unitsml
|
|
|
178
229
|
end
|
|
179
230
|
|
|
180
231
|
def unitname(text, name)
|
|
181
|
-
name ||= unit_instance(text)
|
|
182
|
-
Model::Units::Name.new(
|
|
232
|
+
name ||= unit_en_name(unit_instance(text)) || text
|
|
233
|
+
Model::Units::Name.new(
|
|
234
|
+
name: name,
|
|
235
|
+
lutaml_register: Configuration.context.id,
|
|
236
|
+
)
|
|
183
237
|
end
|
|
184
238
|
|
|
185
239
|
def unitsymbols(formula, options)
|
|
@@ -187,31 +241,44 @@ module Unitsml
|
|
|
187
241
|
Model::Units::Symbol.new(
|
|
188
242
|
type: lang,
|
|
189
243
|
content: formula.public_send(:"to_#{lang.downcase}", options),
|
|
244
|
+
lutaml_register: Configuration.context.id,
|
|
190
245
|
)
|
|
191
246
|
end
|
|
192
247
|
end
|
|
193
248
|
|
|
194
249
|
def unitsystem(units)
|
|
195
250
|
ret = []
|
|
196
|
-
|
|
251
|
+
if units.any? { |u| !u.si_system_type? }
|
|
252
|
+
ret << Model::Units::System.new(
|
|
253
|
+
name: "not_SI",
|
|
254
|
+
type: "not_SI",
|
|
255
|
+
lutaml_register: Configuration.context.id,
|
|
256
|
+
)
|
|
257
|
+
end
|
|
197
258
|
if units.any?(&:si_system_type?)
|
|
198
259
|
if units.size == 1
|
|
199
260
|
base = units[0].downcase_system_type == "si_base"
|
|
200
261
|
base = true if units[0].unit_name == "g" && units[0]&.prefix_name == "k"
|
|
201
262
|
end
|
|
202
|
-
ret << Model::Units::System.new(
|
|
203
|
-
|
|
263
|
+
ret << Model::Units::System.new(
|
|
264
|
+
name: "SI",
|
|
265
|
+
type: (base ? "SI_base" : "SI_derived"),
|
|
266
|
+
lutaml_register: Configuration.context.id,
|
|
267
|
+
)
|
|
204
268
|
end
|
|
205
269
|
ret
|
|
206
270
|
end
|
|
207
271
|
|
|
208
272
|
def dimension(norm_text)
|
|
209
|
-
dim_id = unit_instance(norm_text)
|
|
273
|
+
dim_id = unit_dimension_id(unit_instance(norm_text))
|
|
210
274
|
return unless dim_id
|
|
211
275
|
|
|
212
276
|
dim_attrs = { id: dim_id }
|
|
213
277
|
dimid2dimensions(dim_id)&.compact&.each { |u| dimension1(u, dim_attrs) }
|
|
214
|
-
Model::Dimension.new(
|
|
278
|
+
Model::Dimension.new(
|
|
279
|
+
dim_attrs,
|
|
280
|
+
lutaml_register: Configuration.context.id,
|
|
281
|
+
).to_xml.force_encoding("UTF-8")
|
|
215
282
|
end
|
|
216
283
|
|
|
217
284
|
def dimension1(dim, dims_hash)
|
|
@@ -220,6 +287,7 @@ module Unitsml
|
|
|
220
287
|
dims_hash[underscore(dim_name).to_sym] = dim_klass.new(
|
|
221
288
|
symbol: dim[:symbol],
|
|
222
289
|
power_numerator: float_to_display(dim[:exponent]),
|
|
290
|
+
lutaml_register: Configuration.context.id,
|
|
223
291
|
)
|
|
224
292
|
end
|
|
225
293
|
|
|
@@ -250,23 +318,44 @@ module Unitsml
|
|
|
250
318
|
def prefixes(units, options)
|
|
251
319
|
uniq_prefixes = units.filter_map(&:prefix).uniq(&:prefix_name)
|
|
252
320
|
uniq_prefixes.map do |prefix|
|
|
253
|
-
|
|
254
|
-
prefix_power: prefix&.power, id: prefix&.id }
|
|
255
|
-
type_and_methods = { ASCII: :to_asciimath, unicode: :to_unicode,
|
|
256
|
-
LaTeX: :to_latex, HTML: :to_html }
|
|
257
|
-
prefix_attrs[:name] = Model::Prefixes::Name.new(content: prefix&.name)
|
|
258
|
-
prefix_attrs[:symbol] = type_and_methods.map do |type, method_name|
|
|
259
|
-
Model::Prefixes::Symbol.new(
|
|
260
|
-
type: type,
|
|
261
|
-
content: prefix&.public_send(method_name, options),
|
|
262
|
-
)
|
|
263
|
-
end
|
|
264
|
-
Model::Prefix.new(prefix_attrs).to_xml.force_encoding("UTF-8").gsub(
|
|
265
|
-
"&", "&"
|
|
266
|
-
)
|
|
321
|
+
prefix_xml(prefix, options)
|
|
267
322
|
end.join("\n")
|
|
268
323
|
end
|
|
269
324
|
|
|
325
|
+
def prefix_xml(prefix, options)
|
|
326
|
+
Model::Prefix.new(
|
|
327
|
+
prefix_attributes(prefix, options),
|
|
328
|
+
lutaml_register: Configuration.context.id,
|
|
329
|
+
).to_xml.force_encoding("UTF-8").gsub("&", "&")
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def prefix_attributes(prefix, options)
|
|
333
|
+
{
|
|
334
|
+
prefix_base: prefix&.base,
|
|
335
|
+
prefix_power: prefix&.power,
|
|
336
|
+
id: prefix&.id,
|
|
337
|
+
name: prefix_name(prefix),
|
|
338
|
+
symbol: prefix_symbols(prefix, options),
|
|
339
|
+
}
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def prefix_name(prefix)
|
|
343
|
+
Model::Prefixes::Name.new(
|
|
344
|
+
content: prefix&.name,
|
|
345
|
+
lutaml_register: Configuration.context.id,
|
|
346
|
+
)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def prefix_symbols(prefix, options)
|
|
350
|
+
PREFIX_SYMBOL_METHODS.map do |type, method_name|
|
|
351
|
+
Model::Prefixes::Symbol.new(
|
|
352
|
+
type: type,
|
|
353
|
+
content: prefix&.public_send(method_name, options),
|
|
354
|
+
lutaml_register: Configuration.context.id,
|
|
355
|
+
)
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
270
359
|
def rootunits(units)
|
|
271
360
|
return if units.size == 1 && !units[0].prefix
|
|
272
361
|
|
|
@@ -275,9 +364,15 @@ module Unitsml
|
|
|
275
364
|
attributes[:prefix] = unit.prefix_name if unit.prefix
|
|
276
365
|
unit.power_numerator && unit.power_numerator != "1" and
|
|
277
366
|
attributes[:power_numerator] = unit.power_numerator.raw_value
|
|
278
|
-
Model::Units::EnumeratedRootUnit.new(
|
|
367
|
+
Model::Units::EnumeratedRootUnit.new(
|
|
368
|
+
**attributes,
|
|
369
|
+
lutaml_register: Configuration.context.id,
|
|
370
|
+
)
|
|
279
371
|
end
|
|
280
|
-
Model::Units::RootUnits.new(
|
|
372
|
+
Model::Units::RootUnits.new(
|
|
373
|
+
enumerated_root_unit: enum_root_units,
|
|
374
|
+
lutaml_register: Configuration.context.id,
|
|
375
|
+
)
|
|
281
376
|
end
|
|
282
377
|
|
|
283
378
|
def unit_id(text)
|
|
@@ -288,7 +383,7 @@ module Unitsml
|
|
|
288
383
|
end
|
|
289
384
|
|
|
290
385
|
def format_unit_id(unit, text)
|
|
291
|
-
return unit
|
|
386
|
+
return unit_nist_id(unit)&.gsub("'", "_") if unit
|
|
292
387
|
|
|
293
388
|
text&.gsub("*", ".")&.gsub("^", "")
|
|
294
389
|
end
|
|
@@ -298,7 +393,10 @@ module Unitsml
|
|
|
298
393
|
|
|
299
394
|
dim_attrs = { id: dim_id(dims) }
|
|
300
395
|
dims.map { |u| dimension1(u, dim_attrs) }
|
|
301
|
-
Model::Dimension.new(
|
|
396
|
+
Model::Dimension.new(
|
|
397
|
+
**dim_attrs,
|
|
398
|
+
lutaml_register: Configuration.context.id,
|
|
399
|
+
).to_xml.force_encoding("UTF-8")
|
|
302
400
|
end
|
|
303
401
|
|
|
304
402
|
def quantity(normtext, instance)
|
|
@@ -307,10 +405,36 @@ module Unitsml
|
|
|
307
405
|
|
|
308
406
|
model_quantity_xml(
|
|
309
407
|
instance || unit.quantity_references&.first&.id,
|
|
310
|
-
"##{unit
|
|
408
|
+
"##{unit_dimension_id(unit)}",
|
|
311
409
|
)
|
|
312
410
|
end
|
|
313
411
|
|
|
412
|
+
def unit_nist_id(unit)
|
|
413
|
+
return unless unit
|
|
414
|
+
return unit.nist_id if unit.respond_to?(:nist_id)
|
|
415
|
+
|
|
416
|
+
unit.identifiers&.find { |identifier| identifier.type == "nist" }&.id
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def unit_en_name(unit)
|
|
420
|
+
return unless unit
|
|
421
|
+
return unit.en_name if unit.respond_to?(:en_name)
|
|
422
|
+
|
|
423
|
+
unit.names&.find { |name| name.lang == "en" }&.value
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
def unit_dimension_id(unit)
|
|
427
|
+
return unless unit
|
|
428
|
+
return unit.dimension_url if unit.respond_to?(:dimension_url)
|
|
429
|
+
|
|
430
|
+
unit.dimension_reference&.id ||
|
|
431
|
+
quantity_dimension_id(quantity_instance(unit.quantity_references&.first&.id))
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
def quantity_dimension_id(quantity)
|
|
435
|
+
quantity&.dimension_reference&.id
|
|
436
|
+
end
|
|
437
|
+
|
|
314
438
|
def unit_or_quantity(unit, quantity)
|
|
315
439
|
(unit && unit.quantity_references.size == 1) ||
|
|
316
440
|
quantity_instance(quantity)
|
|
@@ -321,6 +445,7 @@ module Unitsml
|
|
|
321
445
|
id: id,
|
|
322
446
|
name: quantity_name(id),
|
|
323
447
|
dimension_url: url,
|
|
448
|
+
lutaml_register: Configuration.context.id,
|
|
324
449
|
).to_xml.force_encoding("UTF-8")
|
|
325
450
|
end
|
|
326
451
|
|
|
@@ -328,7 +453,7 @@ module Unitsml
|
|
|
328
453
|
quantity_instance(id)&.names&.filter_map do |name|
|
|
329
454
|
next unless name.lang == "en"
|
|
330
455
|
|
|
331
|
-
Model::Quantities::Name.new(content: name.value)
|
|
456
|
+
Model::Quantities::Name.new(content: name.value, lutaml_register: Configuration.context.id)
|
|
332
457
|
end
|
|
333
458
|
end
|
|
334
459
|
|
data/lib/unitsml/version.rb
CHANGED
data/lib/unitsml.rb
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "lutaml/model"
|
|
4
|
-
require "
|
|
4
|
+
require "mml"
|
|
5
5
|
|
|
6
6
|
module Unitsml
|
|
7
7
|
module_function
|
|
8
8
|
|
|
9
9
|
autoload :Dimension, "unitsml/dimension"
|
|
10
|
+
autoload :Configuration, "unitsml/configuration"
|
|
10
11
|
autoload :Errors, "unitsml/errors"
|
|
11
12
|
autoload :Extender, "unitsml/extender"
|
|
12
13
|
autoload :Fenced, "unitsml/fenced"
|
|
13
14
|
autoload :FencedNumeric, "unitsml/fenced_numeric"
|
|
14
15
|
autoload :Formula, "unitsml/formula"
|
|
15
16
|
autoload :IntermediateExpRules, "unitsml/intermediate_exp_rules"
|
|
17
|
+
autoload :MathmlHelper, "unitsml/mathml_helper"
|
|
16
18
|
autoload :Model, "unitsml/model"
|
|
17
19
|
autoload :Namespace, "unitsml/namespace"
|
|
18
20
|
autoload :Number, "unitsml/number"
|
|
@@ -26,54 +28,11 @@ module Unitsml
|
|
|
26
28
|
autoload :Utility, "unitsml/utility"
|
|
27
29
|
autoload :VERSION, "unitsml/version"
|
|
28
30
|
|
|
29
|
-
REGISTER_ID = :unitsml_ruby
|
|
30
|
-
|
|
31
31
|
def parse(string)
|
|
32
32
|
Unitsml::Parser.new(string).parse
|
|
33
33
|
end
|
|
34
|
-
|
|
35
|
-
def register
|
|
36
|
-
@register ||= Lutaml::Model::GlobalRegister.lookup(REGISTER_ID)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def register_model(klass, id:)
|
|
40
|
-
register.register_model(klass, id: id)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def get_class_from_register(class_name)
|
|
44
|
-
register.get_class(class_name)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def register_type_substitution(from:, to:)
|
|
48
|
-
register.register_global_type_substitution(
|
|
49
|
-
from_type: from,
|
|
50
|
-
to_type: to,
|
|
51
|
-
)
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
Lutaml::Model::GlobalRegister.register(
|
|
56
|
-
Lutaml::Model::Register.new(Unitsml::REGISTER_ID),
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
{
|
|
60
|
-
Unitsdb::Unit => Unitsml::Unitsdb::Unit,
|
|
61
|
-
Unitsdb::Units => Unitsml::Unitsdb::Units,
|
|
62
|
-
Unitsdb::Prefixes => Unitsml::Unitsdb::Prefixes,
|
|
63
|
-
Unitsdb::Dimension => Unitsml::Unitsdb::Dimension,
|
|
64
|
-
Unitsdb::PrefixReference => Unitsml::Unitsdb::PrefixReference,
|
|
65
|
-
Unitsdb::DimensionDetails => Unitsml::Unitsdb::DimensionQuantity,
|
|
66
|
-
}.each do |key, value|
|
|
67
|
-
Unitsml.register_type_substitution(from: key, to: value)
|
|
68
34
|
end
|
|
69
35
|
|
|
70
|
-
[
|
|
71
|
-
[Unitsml::Unitsdb::Dimensions, :unitsdb_dimensions],
|
|
72
|
-
[Unitsml::Unitsdb::Prefixes, :unitsdb_prefixes],
|
|
73
|
-
[Unitsml::Unitsdb::Quantities, :unitsdb_quantities],
|
|
74
|
-
[Unitsml::Unitsdb::Units, :unitsdb_units],
|
|
75
|
-
].each { |klass, id| Unitsml.register_model(klass, id: id) }
|
|
76
|
-
|
|
77
36
|
Lutaml::Model::Config.configure do |config|
|
|
78
37
|
config.xml_adapter_type = RUBY_ENGINE == "opal" ? :oga : :ox
|
|
79
38
|
end
|
data/unitsml.gemspec
CHANGED
|
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
|
|
35
35
|
spec.add_dependency "htmlentities"
|
|
36
36
|
spec.add_dependency "lutaml-model", "~> 0.8.0"
|
|
37
|
-
spec.add_dependency "mml", "~> 2.3.
|
|
37
|
+
spec.add_dependency "mml", "~> 2.3.6"
|
|
38
38
|
spec.add_dependency "parslet"
|
|
39
|
-
spec.add_dependency "unitsdb", "~> 2.2.
|
|
39
|
+
spec.add_dependency "unitsdb", "~> 2.2.2"
|
|
40
40
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: unitsml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: htmlentities
|
|
@@ -44,14 +44,14 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 2.3.
|
|
47
|
+
version: 2.3.6
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 2.3.
|
|
54
|
+
version: 2.3.6
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: parslet
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -72,14 +72,14 @@ dependencies:
|
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: 2.2.
|
|
75
|
+
version: 2.2.2
|
|
76
76
|
type: :runtime
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: 2.2.
|
|
82
|
+
version: 2.2.2
|
|
83
83
|
description: Library to work with UnitsML in Ruby
|
|
84
84
|
email:
|
|
85
85
|
- open.source@ribose.com
|
|
@@ -105,15 +105,18 @@ files:
|
|
|
105
105
|
- docs/README.adoc
|
|
106
106
|
- docs/navigation.adoc
|
|
107
107
|
- lib/unitsml.rb
|
|
108
|
+
- lib/unitsml/configuration.rb
|
|
108
109
|
- lib/unitsml/dimension.rb
|
|
109
110
|
- lib/unitsml/errors.rb
|
|
110
111
|
- lib/unitsml/errors/base_error.rb
|
|
112
|
+
- lib/unitsml/errors/opal_payload_not_bundled_error.rb
|
|
111
113
|
- lib/unitsml/errors/plurimath_load_error.rb
|
|
112
114
|
- lib/unitsml/extender.rb
|
|
113
115
|
- lib/unitsml/fenced.rb
|
|
114
116
|
- lib/unitsml/fenced_numeric.rb
|
|
115
117
|
- lib/unitsml/formula.rb
|
|
116
118
|
- lib/unitsml/intermediate_exp_rules.rb
|
|
119
|
+
- lib/unitsml/mathml_helper.rb
|
|
117
120
|
- lib/unitsml/model.rb
|
|
118
121
|
- lib/unitsml/model/dimension.rb
|
|
119
122
|
- lib/unitsml/model/dimension_quantities.rb
|
|
@@ -149,13 +152,13 @@ files:
|
|
|
149
152
|
- lib/unitsml/transform.rb
|
|
150
153
|
- lib/unitsml/unit.rb
|
|
151
154
|
- lib/unitsml/unitsdb.rb
|
|
155
|
+
- lib/unitsml/unitsdb/database.rb
|
|
152
156
|
- lib/unitsml/unitsdb/dimension.rb
|
|
153
|
-
- lib/unitsml/unitsdb/
|
|
157
|
+
- lib/unitsml/unitsdb/dimension_details.rb
|
|
154
158
|
- lib/unitsml/unitsdb/dimensions.rb
|
|
155
159
|
- lib/unitsml/unitsdb/prefix_reference.rb
|
|
156
160
|
- lib/unitsml/unitsdb/prefixes.rb
|
|
157
161
|
- lib/unitsml/unitsdb/quantities.rb
|
|
158
|
-
- lib/unitsml/unitsdb/si_derived_base.rb
|
|
159
162
|
- lib/unitsml/unitsdb/unit.rb
|
|
160
163
|
- lib/unitsml/unitsdb/units.rb
|
|
161
164
|
- lib/unitsml/utility.rb
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unitsml
|
|
4
|
-
module Unitsdb
|
|
5
|
-
class SiDerivedBase < ::Unitsdb::SiDerivedBase
|
|
6
|
-
def prefix_reference=(value)
|
|
7
|
-
return super if value.nil?
|
|
8
|
-
return super if value.is_a?(PrefixReference)
|
|
9
|
-
|
|
10
|
-
super(PrefixReference.new(value.to_hash))
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|