asciimath2unitsml 0.3.1 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +2 -23
- data/.hound.yml +5 -0
- data/.rubocop.yml +4 -8
- data/Gemfile +1 -1
- data/README.adoc +19 -1
- data/Rakefile +1 -1
- data/asciimath2unitsml.gemspec +14 -17
- data/bin/rspec +1 -2
- data/lib/asciimath2unitsml/conv.rb +74 -119
- data/lib/asciimath2unitsml/dimensions.rb +117 -0
- data/lib/asciimath2unitsml/parse.rb +122 -133
- data/lib/asciimath2unitsml/read.rb +42 -0
- data/lib/asciimath2unitsml/render.rb +48 -31
- data/lib/asciimath2unitsml/unit.rb +29 -23
- data/lib/asciimath2unitsml/validate.rb +59 -0
- data/lib/asciimath2unitsml/version.rb +1 -1
- data/lib/asciimath2unitsml.rb +0 -1
- data/lib/unitsdb/dimensions.yaml +65 -8
- data/lib/unitsdb_ruby/unitsdb.rb +87 -55
- data/spec/conv_spec.rb +1443 -1365
- data/spec/spec_helper.rb +10 -10
- metadata +23 -19
@@ -0,0 +1,59 @@
|
|
1
|
+
module Asciimath2UnitsML
|
2
|
+
class Conv
|
3
|
+
def validate_yaml(hash, path)
|
4
|
+
return hash if path == "../unitsdb/quantities.yaml"
|
5
|
+
return hash if path == "../unitsdb/dimensions.yaml"
|
6
|
+
|
7
|
+
hash.each_with_object({}) do |(k, v), m|
|
8
|
+
path == "../unitsdb/units.yaml" and validate_unit(v)
|
9
|
+
m = validate_symbols(m, v)
|
10
|
+
v[:unit_symbols]&.each { |s| validate_unit_symbol_cardinality(s, k) }
|
11
|
+
end
|
12
|
+
hash
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_unit(unit)
|
16
|
+
if unit[:quantity_reference]
|
17
|
+
unit[:quantity_reference].is_a?(Array) or
|
18
|
+
raise StandardError
|
19
|
+
.new "No quantity_reference array provided for unit: #{unit}"
|
20
|
+
end
|
21
|
+
if unit[:unit_name]
|
22
|
+
unit[:unit_name].is_a?(Array) or
|
23
|
+
raise StandardError
|
24
|
+
.new "No unit_name array provided for unit: #{unit}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_symbols(acc, val)
|
29
|
+
symbol = symbol_key(val)
|
30
|
+
!symbol.nil? or
|
31
|
+
raise StandardError.new "No symbol provided for unit: #{val}"
|
32
|
+
Array(symbol)&.each do |s|
|
33
|
+
acc[s] && s != "1" and
|
34
|
+
raise StandardError.new "symbol #{s} is not unique in #{val}: "\
|
35
|
+
"already used for #{acc[s]}"
|
36
|
+
acc[s] = val
|
37
|
+
end
|
38
|
+
acc
|
39
|
+
end
|
40
|
+
|
41
|
+
def validate_unit_symbol_cardinality(sym, key)
|
42
|
+
return true if sym.nil?
|
43
|
+
|
44
|
+
!sym[:id].nil? && !sym[:ascii].nil? && !sym[:html].nil? &&
|
45
|
+
!sym[:mathml].nil? && !sym[:latex].nil? &&
|
46
|
+
!sym[:unicode].nil? and return true
|
47
|
+
raise StandardError.new "malformed unit_symbol for #{key}: #{sym}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def symbol_key(val)
|
51
|
+
symbol = val[:unit_symbols]&.each_with_object([]) do |s, m|
|
52
|
+
m << (s["id"] || s[:id])
|
53
|
+
end || val.dig(:symbol, :ascii) || val[:symbol] # || val[:short]
|
54
|
+
!symbol.nil? && val[:unit_symbols] && !symbol.is_a?(Array) and
|
55
|
+
symbol = [symbol]
|
56
|
+
symbol
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/asciimath2unitsml.rb
CHANGED
data/lib/unitsdb/dimensions.yaml
CHANGED
@@ -3,36 +3,86 @@ NISTd1:
|
|
3
3
|
length:
|
4
4
|
powerNumerator: 1
|
5
5
|
symbol: L
|
6
|
+
dim_symbols:
|
7
|
+
- id: "dim_L"
|
8
|
+
ascii: "L"
|
9
|
+
html: "𝖫"
|
10
|
+
mathml: "<mi mathvariant='sans-serif'>L</mi>"
|
11
|
+
latex: \ensuremath{\mathsf{L}}
|
12
|
+
unicode: "𝖫"
|
13
|
+
|
6
14
|
|
7
15
|
NISTd2:
|
8
16
|
mass:
|
9
17
|
powerNumerator: 1
|
10
18
|
symbol: M
|
19
|
+
dim_symbols:
|
20
|
+
- id: "dim_M"
|
21
|
+
ascii: "M"
|
22
|
+
html: "𝖬"
|
23
|
+
mathml: "<mi mathvariant='sans-serif'>M</mi>"
|
24
|
+
latex: \ensuremath{\mathsf{M}}
|
25
|
+
unicode: "𝖬"
|
11
26
|
|
12
27
|
NISTd3:
|
13
28
|
time:
|
14
29
|
powerNumerator: 1
|
15
30
|
symbol: T
|
31
|
+
dim_symbols:
|
32
|
+
- id: "dim_T"
|
33
|
+
ascii: "T"
|
34
|
+
html: "𝖳"
|
35
|
+
mathml: "<mi mathvariant='sans-serif'>T</mi>"
|
36
|
+
latex: \ensuremath{\mathsf{T}}
|
37
|
+
unicode: "𝖳"
|
16
38
|
|
17
39
|
NISTd4:
|
18
40
|
electric_current:
|
19
41
|
powerNumerator: 1
|
20
42
|
symbol: I
|
43
|
+
dim_symbols:
|
44
|
+
- id: "dim_T"
|
45
|
+
ascii: "T"
|
46
|
+
html: "𝖨"
|
47
|
+
mathml: "<mi mathvariant='sans-serif'>T</mi>"
|
48
|
+
latex: \ensuremath{\mathsf{T}}
|
49
|
+
unicode: "𝖨"
|
21
50
|
|
22
51
|
NISTd5:
|
23
52
|
thermodynamic_temperature:
|
24
53
|
powerNumerator: 1
|
25
|
-
symbol:
|
54
|
+
symbol: Theta
|
55
|
+
dim_symbols:
|
56
|
+
- id: "dim_Theta"
|
57
|
+
ascii: "Theta"
|
58
|
+
html: "𝝠"
|
59
|
+
mathml: "<mi mathvariant='sans-serif'>Θ</mi>"
|
60
|
+
latex: \ensuremath{\mathsf{\Theta}}
|
61
|
+
unicode: "𝝧"
|
26
62
|
|
27
63
|
NISTd6:
|
28
64
|
amount_of_substance:
|
29
65
|
powerNumerator: 1
|
30
66
|
symbol: N
|
67
|
+
dim_symbols:
|
68
|
+
- id: "dim_N"
|
69
|
+
ascii: "N"
|
70
|
+
html: "𝖭"
|
71
|
+
mathml: "<mi mathvariant='sans-serif'>N</mi>"
|
72
|
+
latex: \ensuremath{\mathsf{N}}
|
73
|
+
unicode: "𝖭"
|
31
74
|
|
32
75
|
NISTd7:
|
33
76
|
luminous_intensity:
|
34
77
|
powerNumerator: 1
|
35
78
|
symbol: J
|
79
|
+
dim_symbols:
|
80
|
+
- id: "dim_J"
|
81
|
+
ascii: "J"
|
82
|
+
html: "𝖩"
|
83
|
+
mathml: "<mi mathvariant='sans-serif'>J</mi>"
|
84
|
+
latex: \ensuremath{\mathsf{J}}
|
85
|
+
unicode: "𝖩"
|
36
86
|
|
37
87
|
NISTd8:
|
38
88
|
length:
|
@@ -44,6 +94,13 @@ NISTd9:
|
|
44
94
|
plane_angle:
|
45
95
|
powerNumerator: 1
|
46
96
|
symbol: phi
|
97
|
+
dim_symbols:
|
98
|
+
- id: "dim_phi"
|
99
|
+
ascii: "phi"
|
100
|
+
html: "𝞅"
|
101
|
+
mathml: "<mi mathvariant='sans-serif'>φ</mi>"
|
102
|
+
latex: \ensuremath{\mathsf{\phi}}
|
103
|
+
unicode: "𝞅"
|
47
104
|
|
48
105
|
NISTd10:
|
49
106
|
length:
|
@@ -312,7 +369,7 @@ NISTd39:
|
|
312
369
|
symbol: T
|
313
370
|
thermodynamic_temperature:
|
314
371
|
powerNumerator: -1
|
315
|
-
symbol:
|
372
|
+
symbol: Theta
|
316
373
|
|
317
374
|
NISTd36:
|
318
375
|
length:
|
@@ -367,7 +424,7 @@ NISTd40:
|
|
367
424
|
symbol: T
|
368
425
|
thermodynamic_temperature:
|
369
426
|
powerNumerator: -1
|
370
|
-
symbol:
|
427
|
+
symbol: Theta
|
371
428
|
|
372
429
|
NISTd41:
|
373
430
|
length:
|
@@ -381,7 +438,7 @@ NISTd41:
|
|
381
438
|
symbol: T
|
382
439
|
thermodynamic_temperature:
|
383
440
|
powerNumerator: -1
|
384
|
-
symbol:
|
441
|
+
symbol: Theta
|
385
442
|
|
386
443
|
NISTd46:
|
387
444
|
length:
|
@@ -475,7 +532,7 @@ NISTd48:
|
|
475
532
|
symbol: T
|
476
533
|
thermodynamic_temperature:
|
477
534
|
powerNumerator: -1
|
478
|
-
symbol:
|
535
|
+
symbol: Theta
|
479
536
|
amount_of_substance:
|
480
537
|
powerNumerator: -1
|
481
538
|
symbol: N
|
@@ -603,7 +660,7 @@ NISTd60:
|
|
603
660
|
NISTd68:
|
604
661
|
thermodynamic_temperature:
|
605
662
|
powerNumerator: -1
|
606
|
-
symbol:
|
663
|
+
symbol: Theta
|
607
664
|
|
608
665
|
NISTd69:
|
609
666
|
length:
|
@@ -617,7 +674,7 @@ NISTd69:
|
|
617
674
|
symbol: T
|
618
675
|
thermodynamic_temperature:
|
619
676
|
powerNumerator: -1
|
620
|
-
symbol:
|
677
|
+
symbol: Theta
|
621
678
|
|
622
679
|
NISTd70:
|
623
680
|
length:
|
@@ -639,7 +696,7 @@ NISTd71:
|
|
639
696
|
symbol: T
|
640
697
|
thermodynamic_temperature:
|
641
698
|
powerNumerator: -1
|
642
|
-
symbol:
|
699
|
+
symbol: Theta
|
643
700
|
|
644
701
|
NISTd64:
|
645
702
|
dimensionless: true
|
data/lib/unitsdb_ruby/unitsdb.rb
CHANGED
@@ -1,24 +1,49 @@
|
|
1
1
|
module UnitsDB
|
2
2
|
class Dimension
|
3
|
-
attr_reader :id, :
|
4
|
-
|
3
|
+
attr_reader :id, :name, :symbols, :symbols_hash,
|
4
|
+
:length, :mass, :time, :electric_current,
|
5
|
+
:thermodynamic_temperature,
|
6
|
+
:amount_of_substance, :luminous_intensity, :plane_angle,
|
7
|
+
:dimensionless
|
5
8
|
|
6
9
|
def initialize(id, hash)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
@id = id
|
11
|
+
@dimensionless = hash[:dimensionless]
|
12
|
+
init_dimension(hash)
|
13
|
+
name_dimension(hash)
|
14
|
+
rescue StandardError
|
15
|
+
raise StandardError.new "Parse fail on Dimension #{id}: #{hash}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def init_dimension(hash)
|
19
|
+
hash[:length] and @length = hash[:length][:powerNumerator].to_i
|
20
|
+
hash[:mass] and @mass = hash[:mass][:powerNumerator].to_i
|
21
|
+
hash[:time] and @time = hash[:time][:powerNumerator].to_i
|
22
|
+
hash[:electric_current] and
|
23
|
+
@electric_current = hash[:electric_current][:powerNumerator].to_i
|
24
|
+
hash[:thermodynamic_temperature] and
|
25
|
+
@thermodynamic_temperature = hash[:thermodynamic_temperature][:powerNumerator].to_i
|
26
|
+
hash[:amount_of_substance] and
|
27
|
+
@amount_of_substance = hash[:amount_of_substance][:powerNumerator].to_i
|
28
|
+
hash[:luminous_intensity] and
|
29
|
+
@luminous_intensity = hash[:luminous_intensity][:powerNumerator].to_i
|
30
|
+
hash[:plane_angle] and
|
31
|
+
@plane_angle = hash[:plane_angle][:powerNumerator].to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def name_dimension(hash)
|
35
|
+
acc = %i(length mass time electric_current thermodynamic_temperature
|
36
|
+
amount_of_substance luminous_intensity plane_angle)
|
37
|
+
.each_with_object({}) do |x, m|
|
38
|
+
hash[x] and m[x] = hash[x][:powerNumerator]
|
21
39
|
end
|
40
|
+
return unless acc.keys.size == 1 && acc.values[0] == 1
|
41
|
+
|
42
|
+
dim = acc.keys[0]
|
43
|
+
@name = dim.to_s
|
44
|
+
@symbols = hash[dim][:dim_symbols]
|
45
|
+
@symbols_hash =
|
46
|
+
@symbols&.each_with_object({}) { |h, m| m[h[:id]] = h } || {}
|
22
47
|
end
|
23
48
|
|
24
49
|
def keys
|
@@ -48,24 +73,31 @@ module UnitsDB
|
|
48
73
|
end
|
49
74
|
|
50
75
|
def vector
|
51
|
-
"#{@length}:#{@mass}:#{@time}:#{@electric_current}
|
76
|
+
"#{@length}:#{@mass}:#{@time}:#{@electric_current}:"\
|
77
|
+
"#{@thermodynamic_temperature}:#{@amount_of_substance}:"\
|
52
78
|
"#{@luminous_intensity}:#{@plane_angle}"
|
53
79
|
end
|
80
|
+
|
81
|
+
def symbolid
|
82
|
+
@symbols ? @symbols.first[:id] : nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def symbolids
|
86
|
+
@symbols ? @symbols.map { |s| s[:id] } : []
|
87
|
+
end
|
54
88
|
end
|
55
89
|
|
56
90
|
class Prefix
|
57
91
|
attr_reader :id, :name, :base, :power, :symbol
|
58
92
|
|
59
93
|
def initialize(id, hash)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
raise StandardError.new "Parse fail on Prefix #{id}: #{hash}"
|
68
|
-
end
|
94
|
+
@id = id
|
95
|
+
@name = hash[:name]
|
96
|
+
@base = hash[:base]
|
97
|
+
@power = hash[:power]
|
98
|
+
@symbol = hash[:symbol] # always is a hash
|
99
|
+
rescue StandardError
|
100
|
+
raise StandardError.new "Parse fail on Prefix #{id}: #{hash}"
|
69
101
|
end
|
70
102
|
|
71
103
|
def ascii
|
@@ -97,15 +129,14 @@ module UnitsDB
|
|
97
129
|
attr_reader :id, :dimension, :type, :names, :units
|
98
130
|
|
99
131
|
def initialize(id, hash)
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
end
|
132
|
+
@id = id
|
133
|
+
@dimension = hash[:dimension_url].sub(/^#/, "")
|
134
|
+
@type = hash[:quantity_type]
|
135
|
+
hash[:quantity_name] and @names = hash[:quantity_name]
|
136
|
+
hash[:unit_reference] and
|
137
|
+
@units = hash[:unit_reference].map { |x| x[:url].sub(/^#/, "") }
|
138
|
+
rescue StandardError
|
139
|
+
raise StandardError.new "Parse fail on Quantity #{id}: #{hash}"
|
109
140
|
end
|
110
141
|
|
111
142
|
def name
|
@@ -118,27 +149,28 @@ module UnitsDB
|
|
118
149
|
end
|
119
150
|
|
120
151
|
class Unit
|
121
|
-
attr_reader :id, :dimension, :short, :root, :unit_system, :names,
|
122
|
-
|
152
|
+
attr_reader :id, :dimension, :short, :root, :unit_system, :names,
|
153
|
+
:symbols, :symbols_hash, :root_units, :quantities,
|
154
|
+
:si_derived_bases, :prefixed
|
123
155
|
|
124
156
|
def initialize(id, hash)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
hash[:
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
157
|
+
@id = id
|
158
|
+
@short = short
|
159
|
+
@dimension = hash[:dimension_url].sub(/^#/, "")
|
160
|
+
hash[:short] && !hash[:short].empty? and @short = hash[:short]
|
161
|
+
@unit_system = hash[:unit_system]
|
162
|
+
@names = hash[:unit_name]
|
163
|
+
@symbols_hash =
|
164
|
+
hash[:unit_symbols]&.each_with_object({}) { |h, m| m[h[:id]] = h } || {}
|
165
|
+
@symbols = hash[:unit_symbols]
|
166
|
+
hash[:root_units] and hash[:root_units][:enumerated_root_units] and
|
167
|
+
@root = hash[:root_units][:enumerated_root_units]
|
168
|
+
hash[:quantity_reference] and
|
169
|
+
@quantities = hash[:quantity_reference].map { |x| x[:url].sub(/^#/, "") }
|
170
|
+
hash[:si_derived_bases] and @si_derived_bases = hash[:si_derived_bases]
|
171
|
+
@prefixed = (hash[:prefixed] == true)
|
172
|
+
rescue StandardError
|
173
|
+
raise StandardError.new "Parse fail on Unit #{id}: #{hash}"
|
142
174
|
end
|
143
175
|
|
144
176
|
def system_name
|
@@ -158,7 +190,7 @@ module UnitsDB
|
|
158
190
|
end
|
159
191
|
|
160
192
|
def symbolids
|
161
|
-
@symbols ? @symbols.map { |s| s[:id] } : [
|
193
|
+
@symbols ? @symbols.map { |s| s[:id] } : [@short]
|
162
194
|
end
|
163
195
|
end
|
164
196
|
end
|