asciimath2unitsml 0.3.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Asciimath2UnitsML
2
- VERSION = '0.3.1'.freeze
2
+ VERSION = "0.4.1".freeze
3
3
  end
@@ -1,4 +1,3 @@
1
1
  require_relative "asciimath2unitsml/version"
2
2
  require_relative "asciimath2unitsml/conv"
3
3
  require_relative "unitsdb_ruby/unitsdb"
4
-
@@ -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: "&#x1D5AB;"
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: "&#x1D5AC;"
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: "&#x1D5B3;"
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: "&#x1D5A8;"
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: "&#x1D760;"
59
+ mathml: "<mi mathvariant='sans-serif'>&#x398;</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: "&#x1D5AD;"
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: "&#x1D5A9;"
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: "&#x1D785;"
101
+ mathml: "<mi mathvariant='sans-serif'>&#x3c6;</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
@@ -1,24 +1,49 @@
1
1
  module UnitsDB
2
2
  class Dimension
3
- attr_reader :id, :length, :mass, :time, :electric_current, :thermodynamic_temperature,
4
- :amount_of_substance, :luminous_intensity, :plane_angle, :dimensionless
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
- begin
8
- @id = id
9
- @dimensionless = hash[:dimensionless]
10
- hash[:length] and @length = hash[:length][:powerNumerator].to_i
11
- hash[:mass] and @mass = hash[:mass][:powerNumerator].to_i
12
- hash[:time] and @time = hash[:time][:powerNumerator].to_i
13
- hash[:electric_current] and @electric_current = hash[:electric_current][:powerNumerator].to_i
14
- hash[:thermodynamic_temperature] and
15
- @thermodynamic_temperature = hash[:thermodynamic_temperature][:powerNumerator].to_i
16
- hash[:amount_of_substance] and @amount_of_substance = hash[:amount_of_substance][:powerNumerator].to_i
17
- hash[:luminous_intensity] and @luminous_intensity = hash[:luminous_intensity][:powerNumerator].to_i
18
- hash[:plane_angle] and @plane_angle = hash[:plane_angle][:powerNumerator].to_i
19
- rescue
20
- raise StandardError.new "Parse fail on Dimension #{id}: #{hash}"
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}:#{@thermodynamic_temperature}:#{@amount_of_substance}:"\
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
- begin
61
- @id = id
62
- @name = hash[:name]
63
- @base = hash[:base]
64
- @power = hash[:power]
65
- @symbol = hash[:symbol] # always is a hash
66
- rescue
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
- begin
101
- @id = id
102
- @dimension = hash[:dimension_url].sub(/^#/, "")
103
- @type = hash[:quantity_type]
104
- hash[:quantity_name] and @names = hash[:quantity_name]
105
- hash[:unit_reference] and @units = hash[:unit_reference].map { |x| x[:url].sub(/^#/, "") }
106
- rescue
107
- raise StandardError.new "Parse fail on Quantity #{id}: #{hash}"
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, :symbols, :symbols_hash, :root_units, :quantities,
122
- :si_derived_bases, :prefixed
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
- begin
126
- @id = id
127
- @short = short
128
- @dimension = hash[:dimension_url].sub(/^#/, "")
129
- hash[:short] && !hash[:short].empty? and @short = hash[:short]
130
- @unit_system = hash[:unit_system]
131
- @names = hash[:unit_name]
132
- @symbols_hash = hash[:unit_symbols]&.each_with_object({}) { |h, m| m[h[:id]] = h } || {}
133
- @symbols = hash[:unit_symbols]
134
- hash[:root_units] and hash[:root_units][:enumerated_root_units] and
135
- @root = hash[:root_units][:enumerated_root_units]
136
- hash[:quantity_reference] and @quantities = hash[:quantity_reference].map { |x| x[:url].sub(/^#/, "") }
137
- hash[:si_derived_bases] and @si_derived_bases = hash[:si_derived_bases]
138
- @prefixed = (hash[:prefixed] == true)
139
- rescue
140
- raise StandardError.new "Parse fail on Unit #{id}: #{hash}"
141
- end
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] } : [ @short ]
193
+ @symbols ? @symbols.map { |s| s[:id] } : [@short]
162
194
  end
163
195
  end
164
196
  end