unitsml 0.4.7 → 0.6.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 +4 -4
- data/.github/workflows/rake.yml +8 -0
- data/.github/workflows/release.yml +7 -1
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +498 -0
- data/Gemfile +16 -11
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/docs/README.adoc +106 -4
- data/lib/unitsml/dimension.rb +49 -35
- data/lib/unitsml/errors/base_error.rb +8 -0
- data/lib/unitsml/errors/plurimath_load_error.rb +1 -1
- data/lib/unitsml/errors.rb +8 -0
- data/lib/unitsml/extender.rb +21 -16
- data/lib/unitsml/fenced.rb +97 -0
- data/lib/unitsml/fenced_numeric.rb +13 -0
- data/lib/unitsml/formula.rb +46 -33
- data/lib/unitsml/intermediate_exp_rules.rb +76 -0
- data/lib/unitsml/model/dimension.rb +4 -14
- data/lib/unitsml/model/dimension_quantities/quantity.rb +2 -0
- data/lib/unitsml/model/dimension_quantities.rb +17 -0
- data/lib/unitsml/model/prefix.rb +4 -8
- data/lib/unitsml/model/prefixes/name.rb +5 -4
- data/lib/unitsml/model/prefixes/symbol.rb +3 -2
- data/lib/unitsml/model/prefixes.rb +10 -0
- data/lib/unitsml/model/quantities/name.rb +4 -3
- data/lib/unitsml/model/quantities.rb +9 -0
- data/lib/unitsml/model/quantity.rb +5 -7
- data/lib/unitsml/model/unit.rb +4 -9
- data/lib/unitsml/model/units/enumerated_root_unit.rb +1 -0
- data/lib/unitsml/model/units/name.rb +4 -3
- data/lib/unitsml/model/units/root_units.rb +3 -2
- data/lib/unitsml/model/units/symbol.rb +2 -1
- data/lib/unitsml/model/units/system.rb +4 -3
- data/lib/unitsml/model/units.rb +13 -0
- data/lib/unitsml/model.rb +15 -0
- data/lib/unitsml/namespace.rb +8 -0
- data/lib/unitsml/number.rb +79 -0
- data/lib/unitsml/parse.rb +30 -38
- data/lib/unitsml/parser.rb +27 -13
- data/lib/unitsml/prefix.rb +17 -17
- data/lib/unitsml/sqrt.rb +3 -3
- data/lib/unitsml/transform.rb +143 -50
- data/lib/unitsml/unit.rb +67 -37
- data/lib/unitsml/unitsdb/dimension.rb +14 -20
- data/lib/unitsml/unitsdb/dimension_quantity.rb +2 -6
- data/lib/unitsml/unitsdb/dimensions.rb +3 -9
- data/lib/unitsml/unitsdb/prefix_reference.rb +23 -0
- data/lib/unitsml/unitsdb/prefixes.rb +17 -5
- data/lib/unitsml/unitsdb/quantities.rb +4 -4
- data/lib/unitsml/unitsdb/unit.rb +21 -0
- data/lib/unitsml/unitsdb/units.rb +19 -18
- data/lib/unitsml/unitsdb.rb +14 -5
- data/lib/unitsml/utility.rb +133 -103
- data/lib/unitsml/version.rb +3 -1
- data/lib/unitsml.rb +71 -35
- data/unitsdb/Gemfile +6 -0
- data/unitsdb/LICENSE.md +53 -0
- data/unitsdb/README.adoc +1253 -0
- data/unitsdb/RELEASE-NOTES.adoc +269 -0
- data/unitsdb/dimensions.yaml +1607 -602
- data/unitsdb/prefixes.yaml +842 -301
- data/unitsdb/quantities.yaml +3706 -2458
- data/unitsdb/scales.yaml +97 -0
- data/unitsdb/schemas/README.md +159 -0
- data/unitsdb/schemas/dimensions-schema.yaml +153 -0
- data/unitsdb/schemas/prefixes-schema.yaml +155 -0
- data/unitsdb/schemas/quantities-schema.yaml +117 -0
- data/unitsdb/schemas/scales-schema.yaml +106 -0
- data/unitsdb/schemas/unit_systems-schema.yaml +116 -0
- data/unitsdb/schemas/units-schema.yaml +215 -0
- data/unitsdb/spec/units_spec.rb +13 -10
- data/unitsdb/unit_systems.yaml +77 -15
- data/unitsdb/units.yaml +13517 -9974
- data/unitsdb/validate_schemas.rb +203 -0
- data/unitsml.gemspec +4 -1
- metadata +47 -7
- data/lib/unitsml/error.rb +0 -8
- data/unitsdb/docs/README.adoc +0 -12
- data/unitsdb/docs/navigation.adoc +0 -7
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
module Unitsdb
|
|
5
|
-
class Dimensions
|
|
6
|
-
attr_accessor :dimensions
|
|
7
|
-
|
|
5
|
+
class Dimensions < ::Unitsdb::Dimensions
|
|
8
6
|
def find_by_vector(vector)
|
|
9
|
-
|
|
10
|
-
find
|
|
7
|
+
dimensions.each(&:set_vector)
|
|
8
|
+
dimensions.find { |dim| dim.set_vector == vector }
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
def find_by_id(d_id)
|
|
@@ -26,10 +24,6 @@ module Unitsml
|
|
|
26
24
|
|
|
27
25
|
private
|
|
28
26
|
|
|
29
|
-
def vectored
|
|
30
|
-
@vectored ||= dimensions.each(&:set_vector)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
27
|
def find(field, matching_data)
|
|
34
28
|
dimensions.find { |dim| dim.send(field) == matching_data }
|
|
35
29
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unitsml
|
|
4
|
+
module Unitsdb
|
|
5
|
+
class PrefixReference < ::Unitsdb::PrefixReference
|
|
6
|
+
def base
|
|
7
|
+
prefix.base
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def symbolid
|
|
11
|
+
prefix.symbols.first.ascii
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def power
|
|
15
|
+
prefix.power
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def prefix
|
|
19
|
+
@prefix ||= Unitsdb.prefixes.find_by_id(id)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -2,19 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
module Unitsdb
|
|
5
|
-
class Prefixes
|
|
6
|
-
|
|
5
|
+
class Prefixes < ::Unitsdb::Prefixes
|
|
6
|
+
def find_by_id(p_id)
|
|
7
|
+
find(p_id, :id, :identifiers)
|
|
8
|
+
end
|
|
7
9
|
|
|
8
10
|
def find_by_symbol_name(ascii_sym)
|
|
9
|
-
|
|
11
|
+
find(ascii_sym, :ascii, :symbols)
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def ascii_symbols
|
|
13
15
|
prefixes.each_with_object([]) do |prefix, names_array|
|
|
14
|
-
symbol = prefix.
|
|
16
|
+
symbol = prefix.symbols.map(&:ascii)
|
|
15
17
|
next if symbol.empty?
|
|
16
18
|
|
|
17
|
-
names_array
|
|
19
|
+
names_array.concat(symbol)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def find(matching_data, field, prefix_method)
|
|
26
|
+
prefixes.find do |prefix|
|
|
27
|
+
prefix.public_send(prefix_method.to_sym).find do |object|
|
|
28
|
+
object.public_send(field) == matching_data
|
|
29
|
+
end
|
|
18
30
|
end
|
|
19
31
|
end
|
|
20
32
|
end
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
module Unitsdb
|
|
5
|
-
class Quantities
|
|
6
|
-
attr_accessor :quantities
|
|
7
|
-
|
|
5
|
+
class Quantities < ::Unitsdb::Quantities
|
|
8
6
|
def find_by_id(q_id)
|
|
9
|
-
quantities.find
|
|
7
|
+
quantities.find do |quantity|
|
|
8
|
+
quantity.identifiers.find { |id| id.id == q_id }
|
|
9
|
+
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unitsml
|
|
4
|
+
module Unitsdb
|
|
5
|
+
class Unit < ::Unitsdb::Unit
|
|
6
|
+
def dimension_url
|
|
7
|
+
quantity_id = quantity_references[0].id
|
|
8
|
+
quantity = Unitsdb.quantities.find_by_id(quantity_id)
|
|
9
|
+
quantity.dimension_reference.id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def en_name
|
|
13
|
+
names.find { |name| name.lang == 'en' }&.value
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def nist_id
|
|
17
|
+
identifiers.find { |id| id.type == 'nist' }&.id
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -2,42 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
module Unitsdb
|
|
5
|
-
class Units
|
|
6
|
-
attr_accessor :units
|
|
7
|
-
|
|
5
|
+
class Units < ::Unitsdb::Units
|
|
8
6
|
def find_by_id(u_id)
|
|
9
|
-
|
|
7
|
+
find(u_id, :id, :identifiers)
|
|
10
8
|
end
|
|
11
9
|
|
|
12
10
|
def find_by_name(u_name)
|
|
13
|
-
|
|
14
|
-
unit.unit_symbols.find { |u_sym| u_sym.id == u_name }
|
|
15
|
-
end
|
|
11
|
+
find(u_name, :id, :symbols)
|
|
16
12
|
end
|
|
17
13
|
|
|
18
14
|
def filtered
|
|
19
|
-
@filtered ||=
|
|
20
|
-
|
|
15
|
+
@filtered ||= symbols_ids.reject do |unit|
|
|
16
|
+
%r{\*|\^|/|^1$}.match?(unit) || find_by_symbol_id(unit).prefixed
|
|
21
17
|
end
|
|
22
18
|
end
|
|
23
19
|
|
|
24
20
|
def find_by_symbol_id(sym_id)
|
|
25
|
-
|
|
21
|
+
symbols_hash[sym_id]
|
|
26
22
|
end
|
|
27
23
|
|
|
28
|
-
def
|
|
29
|
-
|
|
24
|
+
def symbols_ids
|
|
25
|
+
symbols_hash.keys
|
|
30
26
|
end
|
|
31
27
|
|
|
32
|
-
def
|
|
33
|
-
@
|
|
28
|
+
def symbols_hash
|
|
29
|
+
@symbols_hash ||= units.each_with_object({}) do |unit, object|
|
|
30
|
+
unit.symbols&.each { |unit_sym| object[unit_sym.id] = unit }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
def find(matching_data, field, unit_method)
|
|
37
|
+
units.find do |unit|
|
|
38
|
+
unit.public_send(unit_method.to_sym).find do |id|
|
|
39
|
+
id.public_send(field) == matching_data
|
|
38
40
|
end
|
|
39
41
|
end
|
|
40
|
-
@symbol_ids_hash
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
end
|
data/lib/unitsml/unitsdb.rb
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
4
|
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
|
+
|
|
5
14
|
class << self
|
|
6
15
|
def load_file(file_name)
|
|
7
16
|
@@hash ||= {}
|
|
@@ -9,19 +18,19 @@ module Unitsml
|
|
|
9
18
|
end
|
|
10
19
|
|
|
11
20
|
def units
|
|
12
|
-
@@units_file ||=
|
|
21
|
+
@@units_file ||= Unitsml.get_class_from_register(:unitsdb_units).from_yaml(load_file(:units))
|
|
13
22
|
end
|
|
14
23
|
|
|
15
24
|
def prefixes
|
|
16
|
-
@@prefixes ||=
|
|
25
|
+
@@prefixes ||= Unitsml.get_class_from_register(:unitsdb_prefixes).from_yaml(load_file(:prefixes))
|
|
17
26
|
end
|
|
18
27
|
|
|
19
28
|
def dimensions
|
|
20
|
-
@@dim_file ||=
|
|
29
|
+
@@dim_file ||= Unitsml.get_class_from_register(:unitsdb_dimensions).from_yaml(load_file(:dimensions))
|
|
21
30
|
end
|
|
22
31
|
|
|
23
32
|
def quantities
|
|
24
|
-
@@quantities ||=
|
|
33
|
+
@@quantities ||= Unitsml.get_class_from_register(:unitsdb_quantities).from_yaml(load_file(:quantities))
|
|
25
34
|
end
|
|
26
35
|
|
|
27
36
|
def prefixes_array
|
|
@@ -37,7 +46,7 @@ module Unitsml
|
|
|
37
46
|
|
|
38
47
|
def valid_path(file_name)
|
|
39
48
|
File.expand_path(
|
|
40
|
-
File.join(__dir__,
|
|
49
|
+
File.join(__dir__, '..', '..', 'unitsdb', "#{file_name}.yaml")
|
|
41
50
|
)
|
|
42
51
|
end
|
|
43
52
|
end
|
data/lib/unitsml/utility.rb
CHANGED
|
@@ -1,37 +1,32 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "unitsml/model/unit"
|
|
4
|
-
require "unitsml/model/prefix"
|
|
5
|
-
require "unitsml/model/quantity"
|
|
6
|
-
require "unitsml/model/dimension"
|
|
7
|
-
|
|
8
3
|
module Unitsml
|
|
9
4
|
module Utility
|
|
10
5
|
# Unit to dimension
|
|
11
6
|
U2D = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
symbol:
|
|
19
|
-
|
|
20
|
-
symbol:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
7
|
+
'm' => { dimension: 'Length', order: 1, symbol: 'L' },
|
|
8
|
+
'g' => { dimension: 'Mass', order: 2, symbol: 'M' },
|
|
9
|
+
'kg' => { dimension: 'Mass', order: 2, symbol: 'M' },
|
|
10
|
+
's' => { dimension: 'Time', order: 3, symbol: 'T' },
|
|
11
|
+
'A' => { dimension: 'ElectricCurrent', order: 4, symbol: 'I' },
|
|
12
|
+
'K' => { dimension: 'ThermodynamicTemperature', order: 5,
|
|
13
|
+
symbol: 'Theta' },
|
|
14
|
+
'degK' => { dimension: 'ThermodynamicTemperature', order: 5,
|
|
15
|
+
symbol: 'Theta' },
|
|
16
|
+
'mol' => { dimension: 'AmountOfSubstance', order: 6, symbol: 'N' },
|
|
17
|
+
'cd' => { dimension: 'LuminousIntensity', order: 7, symbol: 'J' },
|
|
18
|
+
'deg' => { dimension: 'PlaneAngle', order: 8, symbol: 'phi' }
|
|
24
19
|
}.freeze
|
|
25
20
|
# Dimesion for dim_(dimesion) input
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
DIM2D = {
|
|
22
|
+
'dim_L' => U2D['m'],
|
|
23
|
+
'dim_M' => U2D['g'],
|
|
24
|
+
'dim_T' => U2D['s'],
|
|
25
|
+
'dim_I' => U2D['A'],
|
|
26
|
+
'dim_Theta' => U2D['K'],
|
|
27
|
+
'dim_N' => U2D['mol'],
|
|
28
|
+
'dim_J' => U2D['cd'],
|
|
29
|
+
'dim_phi' => U2D['deg']
|
|
35
30
|
}.freeze
|
|
36
31
|
DIMS_VECTOR = %w[
|
|
37
32
|
ThermodynamicTemperature
|
|
@@ -44,6 +39,8 @@ module Unitsml
|
|
|
44
39
|
Time
|
|
45
40
|
].freeze
|
|
46
41
|
|
|
42
|
+
UNKNOWN = 'unknown'
|
|
43
|
+
|
|
47
44
|
class << self
|
|
48
45
|
def unit_instance(unit)
|
|
49
46
|
Unitsdb.units.find_by_symbol_id(unit)
|
|
@@ -55,7 +52,7 @@ module Unitsml
|
|
|
55
52
|
|
|
56
53
|
def units2dimensions(units)
|
|
57
54
|
norm = decompose_units_list(units)
|
|
58
|
-
return if norm.any? { |u| u.nil? || u[:unit]
|
|
55
|
+
return if norm.any? { |u| u.nil? || u[:unit]&.unknown_name? || u[:prefix] == UNKNOWN }
|
|
59
56
|
|
|
60
57
|
norm.map do |u|
|
|
61
58
|
unit_name = u[:unit].unit_name
|
|
@@ -63,7 +60,7 @@ module Unitsml
|
|
|
63
60
|
dimension: U2D[unit_name][:dimension],
|
|
64
61
|
unit: unit_name,
|
|
65
62
|
exponent: u[:unit].power_numerator || 1,
|
|
66
|
-
symbol: U2D[unit_name][:symbol]
|
|
63
|
+
symbol: U2D[unit_name][:symbol]
|
|
67
64
|
}
|
|
68
65
|
end.sort { |a, b| U2D[a[:unit]][:order] <=> U2D[b[:unit]][:order] }
|
|
69
66
|
end
|
|
@@ -72,12 +69,20 @@ module Unitsml
|
|
|
72
69
|
return nil if dims.nil? || dims.empty?
|
|
73
70
|
|
|
74
71
|
dim_hash = dims.each_with_object({}) { |h, m| m[h[:dimension]] = h }
|
|
75
|
-
dims_vector = DIMS_VECTOR.map { |h| dim_hash.dig(h, :exponent) }.join(
|
|
72
|
+
dims_vector = DIMS_VECTOR.map { |h| dim_hash.dig(h, :exponent) }.join(':')
|
|
76
73
|
id = Unitsdb.dimensions.find_by_vector(dims_vector)&.id and return id.to_s
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
|
|
75
|
+
'D_' + dims.map do |d|
|
|
76
|
+
(U2D.dig(d[:unit], :symbol) || DIM2D.dig(d[:id], :symbol)) +
|
|
77
|
+
(to_i_value(d[:exponent]) == 1 ? '' : float_to_display(d[:exponent]))
|
|
78
|
+
end.join('')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def to_i_value(object)
|
|
82
|
+
case object
|
|
83
|
+
when Integer, Float then object
|
|
84
|
+
when Number, Fenced then object.to_i
|
|
85
|
+
end
|
|
81
86
|
end
|
|
82
87
|
|
|
83
88
|
def decompose_units_list(units)
|
|
@@ -85,22 +90,21 @@ module Unitsml
|
|
|
85
90
|
end
|
|
86
91
|
|
|
87
92
|
def decompose_unit(u)
|
|
88
|
-
if u&.unit_name ==
|
|
93
|
+
if u&.unit_name == 'g' || Lutaml::Model::Utils.snake_case(u.system_type) == 'si_base'
|
|
89
94
|
{ unit: u, prefix: u&.prefix }
|
|
90
95
|
elsif u.si_derived_bases.nil? || u.si_derived_bases.empty?
|
|
91
|
-
{ unit: Unit.new(
|
|
96
|
+
{ unit: Unit.new(UNKNOWN) }
|
|
92
97
|
else
|
|
93
98
|
u.si_derived_bases.each_with_object([]) do |k, object|
|
|
94
|
-
prefix = if !k.
|
|
95
|
-
combine_prefixes(prefix_object(k.
|
|
99
|
+
prefix = if !k.prefix_reference.nil?
|
|
100
|
+
combine_prefixes(prefix_object(k.prefix_reference), u.prefix)
|
|
96
101
|
else
|
|
97
102
|
u.prefix
|
|
98
103
|
end
|
|
99
|
-
unit_name = Unitsdb.units.find_by_id(k.id).
|
|
104
|
+
unit_name = Unitsdb.units.find_by_id(k.unit_reference.id).symbols.first.id
|
|
100
105
|
exponent = (k.power&.to_i || 1) * (u.power_numerator&.to_f || 1)
|
|
101
106
|
object << { prefix: prefix,
|
|
102
|
-
|
|
103
|
-
}
|
|
107
|
+
unit: Unit.new(unit_name, exponent, prefix: prefix) }
|
|
104
108
|
end
|
|
105
109
|
end
|
|
106
110
|
end
|
|
@@ -110,15 +114,24 @@ module Unitsml
|
|
|
110
114
|
if m.empty? || m[-1][:unit]&.unit_name != k[:unit]&.unit_name
|
|
111
115
|
m << k
|
|
112
116
|
else
|
|
113
|
-
m[-1][:unit]&.power_numerator = (k
|
|
117
|
+
m[-1][:unit]&.power_numerator = Number.new(numerator_value(k, m))
|
|
114
118
|
m[-1] = {
|
|
115
119
|
prefix: combine_prefixes(prefix_object(m[-1][:prefix]), prefix_object(k[:prefix])),
|
|
116
|
-
unit: m[-1][:unit]
|
|
120
|
+
unit: m[-1][:unit]
|
|
117
121
|
}
|
|
118
122
|
end
|
|
119
123
|
end
|
|
120
124
|
end
|
|
121
125
|
|
|
126
|
+
def numerator_value(unit_hash, unit_array)
|
|
127
|
+
unit_numerator_float(unit_hash) +
|
|
128
|
+
unit_numerator_float(unit_array[-1])
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def unit_numerator_float(object_hash)
|
|
132
|
+
object_hash[:unit]&.power_numerator&.to_f || 1
|
|
133
|
+
end
|
|
134
|
+
|
|
122
135
|
def prefix_object(prefix)
|
|
123
136
|
return prefix unless prefix.is_a?(String)
|
|
124
137
|
return nil unless Unitsdb.prefixes_array.any?(prefix)
|
|
@@ -130,76 +143,68 @@ module Unitsml
|
|
|
130
143
|
return nil if p1.nil? && p2.nil?
|
|
131
144
|
return p1.symbolid if p2.nil?
|
|
132
145
|
return p2.symbolid if p1.nil?
|
|
133
|
-
return
|
|
146
|
+
return UNKNOWN if p1.base != p2.base
|
|
134
147
|
|
|
135
148
|
Unitsdb.prefixes_array.each do |prefix_name|
|
|
136
149
|
p = prefix_object(prefix_name)
|
|
137
150
|
return p if p.base == p1.base && p.power == p1.power + p2.power
|
|
138
151
|
end
|
|
139
152
|
|
|
140
|
-
|
|
153
|
+
UNKNOWN
|
|
141
154
|
end
|
|
142
155
|
|
|
143
156
|
def unit(units, formula, dims, norm_text, name, options)
|
|
144
157
|
attributes = {
|
|
145
158
|
id: unit_id(norm_text),
|
|
146
159
|
system: unitsystem(units),
|
|
147
|
-
name: unitname(
|
|
160
|
+
name: unitname(norm_text, name),
|
|
148
161
|
symbol: unitsymbols(formula, options),
|
|
149
|
-
root_units: rootunits(units)
|
|
162
|
+
root_units: rootunits(units)
|
|
150
163
|
}
|
|
151
164
|
attributes[:dimension_url] = "##{dim_id(dims)}" if dims
|
|
152
165
|
Model::Unit.new(attributes).to_xml
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def unitname(units, text, name)
|
|
161
|
-
Model::Units::Name.new(
|
|
162
|
-
name: unit_instance(text)&.unit_name&.first || text
|
|
163
|
-
)
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def postprocess_normtext(units)
|
|
167
|
-
units.map { |u| "#{u.prefix_name}#{u.unit_name}#{display_exp(u)}" }.join("*")
|
|
166
|
+
.force_encoding('UTF-8')
|
|
167
|
+
.gsub('<', '<')
|
|
168
|
+
.gsub('>', '>')
|
|
169
|
+
.gsub('&', '&')
|
|
170
|
+
.gsub(/−/, '−')
|
|
171
|
+
.gsub(/⋅/, '⋅')
|
|
168
172
|
end
|
|
169
173
|
|
|
170
|
-
def
|
|
171
|
-
|
|
174
|
+
def unitname(text, name)
|
|
175
|
+
name ||= unit_instance(text)&.en_name || text
|
|
176
|
+
Model::Units::Name.new(name: name)
|
|
172
177
|
end
|
|
173
178
|
|
|
174
179
|
def unitsymbols(formula, options)
|
|
175
180
|
%w[HTML MathMl].map do |lang|
|
|
176
|
-
Model::Units::Symbol.new(
|
|
181
|
+
Model::Units::Symbol.new(
|
|
182
|
+
type: lang,
|
|
183
|
+
content: formula.public_send(:"to_#{lang.downcase}", options)
|
|
184
|
+
)
|
|
177
185
|
end
|
|
178
186
|
end
|
|
179
187
|
|
|
180
188
|
def unitsystem(units)
|
|
181
189
|
ret = []
|
|
182
|
-
if units.any? { |u| u.
|
|
183
|
-
|
|
184
|
-
end
|
|
185
|
-
if units.any? { |u| u.system_name == "SI" }
|
|
190
|
+
ret << Model::Units::System.new(name: 'not_SI', type: 'not_SI') if units.any? { |u| !u.si_system_type? }
|
|
191
|
+
if units.any?(&:si_system_type?)
|
|
186
192
|
if units.size == 1
|
|
187
|
-
base = units[0].
|
|
188
|
-
base = true if units[0].unit_name ==
|
|
193
|
+
base = units[0].downcase_system_type == 'si_base'
|
|
194
|
+
base = true if units[0].unit_name == 'g' && units[0]&.prefix_name == 'k'
|
|
189
195
|
end
|
|
190
|
-
ret << Model::Units::System.new(name:
|
|
196
|
+
ret << Model::Units::System.new(name: 'SI', type: (base ? 'SI_base' : 'SI_derived'))
|
|
191
197
|
end
|
|
192
198
|
ret
|
|
193
199
|
end
|
|
194
200
|
|
|
195
201
|
def dimension(norm_text)
|
|
196
|
-
|
|
197
|
-
return unless
|
|
202
|
+
dim_id = unit_instance(norm_text)&.dimension_url
|
|
203
|
+
return unless dim_id
|
|
198
204
|
|
|
199
|
-
dim_id = dim_url.sub("#", '')
|
|
200
205
|
dim_attrs = { id: dim_id }
|
|
201
206
|
dimid2dimensions(dim_id)&.compact&.each { |u| dimension1(u, dim_attrs) }
|
|
202
|
-
Model::Dimension.new(dim_attrs).to_xml
|
|
207
|
+
Model::Dimension.new(dim_attrs).to_xml.force_encoding('UTF-8')
|
|
203
208
|
end
|
|
204
209
|
|
|
205
210
|
def dimension1(dim, dims_hash)
|
|
@@ -212,26 +217,31 @@ module Unitsml
|
|
|
212
217
|
end
|
|
213
218
|
|
|
214
219
|
def float_to_display(float)
|
|
215
|
-
float
|
|
220
|
+
case float
|
|
221
|
+
when Integer, Float
|
|
222
|
+
float.to_f.round(1).to_s.sub(/\.0$/, '')
|
|
223
|
+
when Number, Fenced
|
|
224
|
+
float.float_to_display
|
|
225
|
+
end
|
|
216
226
|
end
|
|
217
227
|
|
|
218
228
|
def dimid2dimensions(normtext)
|
|
219
229
|
dims = Unitsdb.dimensions.find_by_id(normtext)
|
|
220
230
|
dims&.processed_keys&.map do |processed_key|
|
|
221
|
-
humanized = processed_key.split(
|
|
231
|
+
humanized = processed_key.split('_').map(&:capitalize).join
|
|
222
232
|
next unless DIMS_VECTOR.include?(humanized)
|
|
223
233
|
|
|
224
234
|
dim_quantity = dims.public_send(processed_key)
|
|
225
235
|
{
|
|
226
236
|
dimension: humanized,
|
|
227
237
|
symbol: dim_quantity.symbol,
|
|
228
|
-
exponent: dim_quantity.
|
|
238
|
+
exponent: dim_quantity.power
|
|
229
239
|
}
|
|
230
240
|
end
|
|
231
241
|
end
|
|
232
242
|
|
|
233
243
|
def prefixes(units, options)
|
|
234
|
-
uniq_prefixes = units.map
|
|
244
|
+
uniq_prefixes = units.map(&:prefix).compact.uniq(&:prefix_name)
|
|
235
245
|
uniq_prefixes.map do |prefix|
|
|
236
246
|
prefix_attrs = { prefix_base: prefix&.base, prefix_power: prefix&.power, id: prefix&.id }
|
|
237
247
|
type_and_methods = { ASCII: :to_asciimath, unicode: :to_unicode, LaTeX: :to_latex, HTML: :to_html }
|
|
@@ -239,10 +249,10 @@ module Unitsml
|
|
|
239
249
|
prefix_attrs[:symbol] = type_and_methods.map do |type, method_name|
|
|
240
250
|
Model::Prefixes::Symbol.new(
|
|
241
251
|
type: type,
|
|
242
|
-
content: prefix&.public_send(method_name, options)
|
|
252
|
+
content: prefix&.public_send(method_name, options)
|
|
243
253
|
)
|
|
244
254
|
end
|
|
245
|
-
Model::Prefix.new(prefix_attrs).to_xml.gsub(
|
|
255
|
+
Model::Prefix.new(prefix_attrs).to_xml.force_encoding('UTF-8').gsub('&', '&')
|
|
246
256
|
end.join("\n")
|
|
247
257
|
end
|
|
248
258
|
|
|
@@ -252,18 +262,24 @@ module Unitsml
|
|
|
252
262
|
enum_root_units = units.map do |unit|
|
|
253
263
|
attributes = { unit: unit.enumerated_name }
|
|
254
264
|
attributes[:prefix] = unit.prefix_name if unit.prefix
|
|
255
|
-
unit.power_numerator && unit.power_numerator !=
|
|
256
|
-
attributes[:power_numerator] = unit.power_numerator
|
|
265
|
+
unit.power_numerator && unit.power_numerator != '1' and
|
|
266
|
+
attributes[:power_numerator] = unit.power_numerator.raw_value
|
|
257
267
|
Model::Units::EnumeratedRootUnit.new(attributes)
|
|
258
268
|
end
|
|
259
269
|
Model::Units::RootUnits.new(enumerated_root_unit: enum_root_units)
|
|
260
270
|
end
|
|
261
271
|
|
|
262
272
|
def unit_id(text)
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
273
|
+
text = text&.gsub(/[()]/, '')
|
|
274
|
+
unit = unit_instance(text)
|
|
275
|
+
|
|
276
|
+
format_unit_id(unit, text)&.insert(0, 'U_')
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def format_unit_id(unit, text)
|
|
280
|
+
return unit.nist_id&.gsub(/'/, '_') if unit
|
|
281
|
+
|
|
282
|
+
text&.gsub(/\*/, '.')&.gsub(/\^/, '')
|
|
267
283
|
end
|
|
268
284
|
|
|
269
285
|
def dimension_components(dims)
|
|
@@ -271,45 +287,59 @@ module Unitsml
|
|
|
271
287
|
|
|
272
288
|
dim_attrs = { id: dim_id(dims) }
|
|
273
289
|
dims.map { |u| dimension1(u, dim_attrs) }
|
|
274
|
-
Model::Dimension.new(dim_attrs).to_xml
|
|
290
|
+
Model::Dimension.new(dim_attrs).to_xml.force_encoding('UTF-8')
|
|
275
291
|
end
|
|
276
292
|
|
|
277
|
-
def quantity(normtext,
|
|
293
|
+
def quantity(normtext, instance)
|
|
278
294
|
unit = unit_instance(normtext)
|
|
279
|
-
return unless unit
|
|
295
|
+
return unless unit_or_quantity(unit, instance)
|
|
296
|
+
|
|
297
|
+
model_quantity_xml(
|
|
298
|
+
instance || unit.quantity_references&.first&.id,
|
|
299
|
+
"##{unit.dimension_url}"
|
|
300
|
+
)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def unit_or_quantity(unit, quantity)
|
|
304
|
+
unit && unit.quantity_references.size == 1 ||
|
|
280
305
|
quantity_instance(quantity)
|
|
306
|
+
end
|
|
281
307
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
308
|
+
def model_quantity_xml(id, url)
|
|
309
|
+
Model::Quantity.new(
|
|
310
|
+
id: id,
|
|
311
|
+
name: quantity_name(id),
|
|
312
|
+
dimension_url: url
|
|
313
|
+
).to_xml.force_encoding('UTF-8')
|
|
286
314
|
end
|
|
287
315
|
|
|
288
316
|
def quantity_name(id)
|
|
289
|
-
quantity_instance(id)&.
|
|
290
|
-
|
|
317
|
+
quantity_instance(id)&.names&.filter_map do |name|
|
|
318
|
+
next unless name.lang == 'en'
|
|
319
|
+
|
|
320
|
+
Model::Quantities::Name.new(content: name.value)
|
|
291
321
|
end
|
|
292
322
|
end
|
|
293
323
|
|
|
294
324
|
def string_to_html_entity(string)
|
|
295
|
-
|
|
296
|
-
entities.encode(
|
|
325
|
+
HTMLEntities.new.encode(
|
|
297
326
|
string.frozen? ? string : string.force_encoding('UTF-8'),
|
|
298
|
-
:hexadecimal
|
|
327
|
+
:hexadecimal
|
|
299
328
|
)
|
|
300
329
|
end
|
|
301
330
|
|
|
302
331
|
def html_entity_to_unicode(string)
|
|
303
|
-
|
|
304
|
-
entities.decode(string)
|
|
332
|
+
HTMLEntities.new.decode(string)
|
|
305
333
|
end
|
|
306
334
|
|
|
307
335
|
def underscore(str)
|
|
308
336
|
str.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
|
|
309
337
|
end
|
|
310
338
|
|
|
311
|
-
def
|
|
312
|
-
|
|
339
|
+
def set_to_fence(set)
|
|
340
|
+
return set if set.is_a?(Fenced)
|
|
341
|
+
|
|
342
|
+
Fenced.new('(', set, ')')
|
|
313
343
|
end
|
|
314
344
|
end
|
|
315
345
|
end
|