asciimath2unitsml 0.1.3 → 0.2.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.
@@ -3,27 +3,79 @@ module Asciimath2UnitsML
3
3
  include Rsec::Helpers
4
4
 
5
5
  def read_yaml(path)
6
- symbolize_keys(YAML.load_file(File.join(File.join(File.dirname(__FILE__), path))))
6
+ validate_yaml(symbolize_keys(YAML.load_file(File.join(File.join(File.dirname(__FILE__), path)))), path)
7
7
  end
8
8
 
9
- def flip_name_and_id(yaml)
10
- yaml.each_with_object({}) do |(k, v), m|
11
- next if v[:name].nil? || v[:name].empty?
12
- symbol = v[:symbol] || v[:short]
13
- m[symbol.to_sym] = v
14
- m[symbol.to_sym][:symbol] = symbol
15
- m[symbol.to_sym][:id] = k.to_s
9
+ def flip_name_and_symbol(hash)
10
+ hash.each_with_object({}) do |(k, v), m|
11
+ next if v.name.nil? || v.name.empty?
12
+ m[v.symbolid] = v
16
13
  end
17
14
  end
18
15
 
16
+ def flip_name_and_symbols(hash)
17
+ hash.each_with_object({}) do |(k, v), m|
18
+ next if v.name.nil? || v.name.empty?
19
+ v.symbolids.each { |s| m[s] = v }
20
+ end
21
+ end
22
+
23
+ def validate_yaml(hash, path)
24
+ return hash if path == "../unitsdb/quantities.yaml"
25
+ return hash if path == "../unitsdb/dimensions.yaml"
26
+ hash.each_with_object({}) do |(k, v), m|
27
+ path == "../unitsdb/units.yaml" and validate_unit(v)
28
+ m = validate_symbols(m, v)
29
+ v[:unit_symbols]&.each { |s| validate_unit_symbol_cardinality(s, k) }
30
+ end
31
+ hash
32
+ end
33
+
34
+ def validate_unit(v)
35
+ if v[:quantity_reference]
36
+ v[:quantity_reference].is_a?(Array) or
37
+ raise StandardError.new "No quantity_reference array provided for unit: #{v}"
38
+ end
39
+ if v[:unit_name]
40
+ v[:unit_name].is_a?(Array) or raise StandardError.new "No unit_name array provided for unit: #{v}"
41
+ end
42
+ end
43
+
44
+ def validate_symbols(m, v)
45
+ symbol = symbol_key(v)
46
+ !symbol.nil? or raise StandardError.new "No symbol provided for unit: #{v}"
47
+ Array(symbol)&.each do |s|
48
+ m[s] && s != "1" and
49
+ raise StandardError.new "symbol #{s} is not unique in #{v}: already used for #{m[s]}"
50
+ m[s] = v
51
+ end
52
+ m
53
+ end
54
+
55
+ def validate_unit_symbol_cardinality(us, k)
56
+ return true if us.nil?
57
+ !us[:id].nil? && !us[:ascii].nil? && !us[:html].nil? && !us[:mathml].nil? && !us[:latex].nil? &&
58
+ !us[:unicode].nil? and return true
59
+ raise StandardError.new "malformed unit_symbol for #{k}: #{us}"
60
+ end
61
+
62
+ def symbol_key(v)
63
+ symbol = v[:unit_symbols]&.each_with_object([]) { |s, m| m << (s["id"] || s[:id]) } ||
64
+ v.dig(:symbol, :ascii) || v[:symbol] #|| v[:short]
65
+ symbol = [symbol] if !symbol.nil? && v[:unit_symbols] && !symbol.is_a?(Array)
66
+ symbol
67
+ end
68
+
19
69
  def symbolize_keys(hash)
20
- hash.inject({})do |result, (key, value)|
70
+ return hash if hash.is_a? String
71
+ hash.inject({}) do |result, (key, value)|
21
72
  new_key = case key
22
73
  when String then key.to_sym
23
74
  else key
24
75
  end
25
76
  new_value = case value
26
77
  when Hash then symbolize_keys(value)
78
+ when Array then value.map { |m| symbolize_keys(m) }
27
79
  else value
28
80
  end
29
81
  result[new_key] = new_value
@@ -32,37 +84,50 @@ module Asciimath2UnitsML
32
84
  end
33
85
 
34
86
  def parser
35
- prefix = /#{@prefixes.keys.join("|")}/.r
87
+ prefix2 = /#{@prefixes.keys.select { |x| x.size == 2 }.join("|")}/.r
88
+ prefix1 = /#{@prefixes.keys.select { |x| x.size == 1 }.join("|")}/.r
36
89
  unit_keys = @units.keys.reject do |k|
37
- @units[k][:type]&.include?("buildable") || /\*|\^/.match(k)
90
+ /\*|\^|\/|^1$/.match(k) || @units[k].prefixed
38
91
  end.map { |k| Regexp.escape(k) }
39
92
  unit1 = /#{unit_keys.sort_by(&:length).reverse.join("|")}/.r
40
93
  exponent = /\^\(-?\d+\)/.r.map { |m| m.sub(/\^/, "").gsub(/[()]/, "") } |
41
94
  /\^-?\d+/.r.map { |m| m.sub(/\^/, "") }
42
95
  multiplier = %r{\*|//|/}.r.map { |x| { multiplier: x[0] } }
43
- unit = seq(unit1, exponent._?) { |x| { prefix: nil, unit: x[0], display_exponent: (x[1][0] )} } |
44
- seq(prefix, unit1, exponent._?) { |x| { prefix: x[0][0], unit: x[1], display_exponent: (x[2][0] ) } }
45
- units_tail = seq(multiplier, unit) { |x| [x[0], x[1]] }
46
- units = seq(unit, units_tail.star) { |x| [x[0], x[1]].flatten }
96
+ unit =
97
+ seq("sqrt(", unit1, ")") { |x| { prefix: nil, unit: x[1], display_exponent: "0.5" } } |
98
+ seq("sqrt(", prefix1, unit1, ")") { |x| { prefix: x[1], unit: x[2], display_exponent: "0.5" } } |
99
+ seq("sqrt(", prefix2, unit1, ")") { |x| { prefix: x[1], unit: x[2], display_exponent: "0.5" } } |
100
+ seq(unit1, exponent._? & multiplier) { |x| { prefix: nil, unit: x[0], display_exponent: (x[1][0] )} } |
101
+ seq(unit1, exponent._?).eof { |x| { prefix: nil, unit: x[0], display_exponent: (x[1][0] )} } |
102
+ seq(prefix1, unit1, exponent._? ) { |x| { prefix: x[0], unit: x[1], display_exponent: (x[2][0] ) } } |
103
+ seq(prefix2, unit1, exponent._? ) { |x| { prefix: x[0], unit: x[1], display_exponent: (x[2][0] ) } } |
104
+ "1".r.map { |_| { prefix: nil, unit: "1", display_exponent: nil } }
105
+ units = seq(prefix2, "-") { |x| [{ prefix: x[0], unit: nil, display_exponent: nil }] } |
106
+ seq(prefix1, "-") { |x| [{ prefix: x[0], unit: nil, display_exponent: nil }] } |
107
+ unit.join(multiplier)
47
108
  parser = units.eof
48
109
  end
49
110
 
50
111
  def parse(x)
51
- units = @parser.parse(x)
112
+ text = Array(x.split(/,\s*/))
113
+ units = @parser.parse!(text[0])
52
114
  if !units || Rsec::INVALID[units]
53
115
  raise Rsec::SyntaxError.new "error parsing UnitsML expression", x, 1, 0
54
116
  end
55
117
  Rsec::Fail.reset
56
- postprocess(units, x)
118
+ postprocess(units, text)
57
119
  end
58
120
 
59
121
  def postprocess(units, text)
60
122
  units = postprocess1(units)
123
+ quantity = text[1..-1]&.select { |x| /^quantity:/.match(x) }&.first&.sub(/^quantity:\s*/, "")
124
+ name = text[1..-1]&.select { |x| /^name:/.match(x) }&.first&.sub(/^name:\s*/, "")
125
+ symbol = text[1..-1]&.select { |x| /^symbol:/.match(x) }&.first&.sub(/^symbol:\s*/, "")
61
126
  normtext = units_only(units).each.map do |u|
62
127
  exp = u[:exponent] && u[:exponent] != "1" ? "^#{u[:exponent]}" : ""
63
128
  "#{u[:prefix]}#{u[:unit]}#{exp}"
64
129
  end.join("*")
65
- [units, text, normtext]
130
+ [units, text[0], normtext, quantity, name, symbol]
66
131
  end
67
132
 
68
133
  def postprocess1(units)
@@ -78,17 +143,6 @@ module Asciimath2UnitsML
78
143
  end
79
144
  end
80
145
 
81
- U2D = {
82
- "m" => { dimension: "Length", order: 1, symbol: "L" },
83
- "g" => { dimension: "Mass", order: 2, symbol: "M" },
84
- "kg" => { dimension: "Mass", order: 2, symbol: "M" },
85
- "s" => { dimension: "Time", order: 3, symbol: "T" },
86
- "A" => { dimension: "ElectricCurrent", order: 4, symbol: "I" },
87
- "K" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" },
88
- "mol" => { dimension: "AmountOfSubstance", order: 6, symbol: "N" },
89
- "cd" => { dimension: "LuminousIntensity", order: 7, symbol: "J" },
90
- }
91
-
92
146
  def Asciimath2UnitsML(expression)
93
147
  xml = Nokogiri::XML(asciimath2mathml(expression))
94
148
  MathML2UnitsML(xml).to_xml
@@ -100,10 +154,29 @@ module Asciimath2UnitsML
100
154
  xml.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
101
155
  next unless %r{^unitsml\(.+\)$}.match(x.text)
102
156
  text = x.text.sub(%r{^unitsml\((.+)\)$}m, "\\1")
103
- units, origtext, normtext = parse(text)
104
- delim = x&.previous_element&.name == "mn" ? "<mo rspace='thickmathspace'>&#x2062;</mo>" : ""
105
- x.replace("#{delim}<mrow xref='#{unit_id(text)}'>#{mathmlsymbol(units)}</mrow>\n"\
106
- "#{unitsml(units, origtext, normtext)}")
157
+ units, origtext, normtext, quantity, name, symbol = parse(text)
158
+ rendering = symbol ? embeddedmathml(asciimath2mathml(symbol)) : mathmlsymbol(units, false)
159
+ x.replace("#{delimspace(rendering, x)}<mrow xref='#{unit_id(origtext)}'>#{rendering}</mrow>\n"\
160
+ "#{unitsml(units, origtext, normtext, quantity, name)}")
161
+ end
162
+ dedup_ids(xml)
163
+ end
164
+
165
+ def delimspace(rendering, elem)
166
+ return "" if elem&.previous_element && elem&.previous_element.name != "mn"
167
+ text = HTMLEntities.new.encode(Nokogiri::XML("<mrow>#{rendering}</mrow>").text.strip)
168
+ /\p{L}|\p{N}/.match(text) ?
169
+ "<mo rspace='thickmathspace'>&#x2062;</mo>" : "<mo>&#x2062;</mo>"
170
+ end
171
+
172
+ def dedup_ids(xml)
173
+ %w(Unit Dimension Prefix Quantity).each do |t|
174
+ xml.xpath(".//m:#{t}/@xml:id", "m" => UNITSML_NS).map { |a| a.text }.uniq.each do |v|
175
+ xml.xpath(".//*[@xml:id = '#{v}']").each_with_index do |n, i|
176
+ next if i == 0
177
+ n.remove
178
+ end
179
+ end
107
180
  end
108
181
  xml
109
182
  end
@@ -113,5 +186,43 @@ module Asciimath2UnitsML
113
186
  AsciiMath.parse(HTMLEntities.new.decode(expression)).ast).to_s.
114
187
  gsub(/<math>/, "<math xmlns='#{MATHML_NS}'>")
115
188
  end
189
+
190
+ def embeddedmathml(mathml)
191
+ x = Nokogiri::XML(mathml)
192
+ x.xpath(".//m:mi", "m" => MATHML_NS).each { |mi| mi["mathvariant"] = "normal" }
193
+ x.children.to_xml
194
+ end
195
+
196
+ def ambig_units
197
+ u = @units_id.each_with_object({}) do |(k, v), m|
198
+ v.symbolids.each do |x|
199
+ next if %r{[*/^]}.match(x)
200
+ next unless v.symbols_hash[x][:html] != x
201
+ m[v.symbols_hash[x][:html]] ||= []
202
+ m[v.symbols_hash[x][:html]] << x
203
+ end
204
+ end
205
+ u.keys.each { |k| u[k] = u[k].unshift(k) if @symbols.dig(k, :html) == k }
206
+ render_ambig_units(u)
207
+ end
208
+
209
+ def render_ambig_units(u)
210
+ maxcols = 0
211
+ u.each { |_, v| maxcols = v.size if maxcols < v.size }
212
+ puts %([cols="#{maxcols + 1}*"]\n|===\n|Symbol | Unit + ID #{"| " * (maxcols - 1)}\n)
213
+ puts "\n\n"
214
+ u.keys.sort_by { |a| [-u[a].size, a.gsub(%r{\&[^;]+;}, "").gsub(/[^A-Za-z]/, "").downcase] }.each do |k|
215
+ print "| #{html2adoc(k)} "
216
+ u[k].sort_by { |v1| v1.size }.each { |v1| print "| #{@units[v1].name}: `#{v1}` " }
217
+ puts "#{"| " * (maxcols - u[k].size) }\n"
218
+ end
219
+ puts "|===\n"
220
+ end
221
+
222
+ def html2adoc(k)
223
+ k.gsub(%r{<i>}, "__").gsub(%r{</i>}, "__")
224
+ .gsub(%r{<sup>}, "^").gsub(%r{</sup>}, "^")
225
+ .gsub(%r{<sub>}, "~").gsub(%r{</sub>}, "~")
226
+ end
116
227
  end
117
228
  end
@@ -0,0 +1,83 @@
1
+ module Asciimath2UnitsML
2
+ class Conv
3
+ def multiplier(x)
4
+ case x
5
+ when :space
6
+ { html: "&#xA0;", mathml: "<mo rspace='thickmathspace'>&#x2062;</mo>" }
7
+ when :nospace
8
+ { html: "", mathml: "<mo>&#x2062;</mo>" }
9
+ else
10
+ { html: HTMLEntities.new.encode(x), mathml: "<mo>#{HTMLEntities.new.encode(x)}</mo>" }
11
+ end
12
+ end
13
+
14
+ def render(unit, style)
15
+ @symbols[unit][style] || unit
16
+ end
17
+
18
+ def htmlent(x)
19
+ HTMLEntities.new.decode(x).split(/([<>&])/)
20
+ .map { |c| /[<>'"]/.match(c) ? c : HTMLEntities.new.encode(c, :hexadecimal) }.join
21
+ end
22
+
23
+ def htmlsymbol(units, normalise)
24
+ units.map do |u|
25
+ if u[:multiplier] then u[:multiplier] == "*" ? @multiplier[:html] : u[:multiplier]
26
+ elsif u[:unit].nil? && u[:prefix]
27
+ @prefixes[u[:prefix]].html
28
+ else
29
+ base = (u[:prefix] || "") + render(normalise ? @units[u[:unit]].symbolid : u[:unit], :html)
30
+ htmlsymbol_exponent(u, base)
31
+ end
32
+ end.join("")
33
+ end
34
+
35
+ def htmlsymbol_exponent(u, base)
36
+ if u[:display_exponent] == "0.5"
37
+ base = "&#x221a;#{base}"
38
+ elsif u[:display_exponent]
39
+ exp = "<sup>#{u[:display_exponent].sub(/-/, "&#x2212;")}</sup>"
40
+ base += exp
41
+ end
42
+ base
43
+ end
44
+
45
+ def mathmlsymbol(units, normalise)
46
+ exp = units.map do |u|
47
+ if u[:multiplier] then u[:multiplier] == "*" ? @multiplier[:mathml] : "<mo>#{u[:multiplier]}</mo>"
48
+ elsif u[:unit].nil? && u[:prefix]
49
+ %(<mi mathvariant='normal'>#{htmlent(@prefixes[u[:prefix]].html)}</mi>)
50
+ else
51
+ mathmlsymbol1(u, normalise)
52
+ end
53
+ end.join("")
54
+ end
55
+
56
+ def mathmlsymbol1(u, normalise)
57
+ base = render(normalise ? @units[u[:unit]].symbolid : u[:unit], :mathml)
58
+ if u[:prefix]
59
+ prefix = htmlent(@prefixes[u[:prefix]].html)
60
+ base = base.match(/<mi mathvariant='normal'>/) ?
61
+ base.sub(/<mi mathvariant='normal'>/, "<mi mathvariant='normal'>#{prefix}") :
62
+ "<mrow><mi mathvariant='normal'>#{prefix}#{base}</mrow>"
63
+ end
64
+ mathmlsymbol_exponent(u, base)
65
+ end
66
+
67
+ def mathmlsymbol_exponent(u, base)
68
+ if u[:display_exponent] == "0.5"
69
+ base = "<msqrt>#{base}</msqrt>"
70
+ elsif u[:display_exponent]
71
+ exp = "<mn>#{u[:display_exponent]}</mn>".sub(/<mn>-/, "<mo>&#x2212;</mo><mn>")
72
+ base = "<msup><mrow>#{base}</mrow><mrow>#{exp}</mrow></msup>"
73
+ end
74
+ base
75
+ end
76
+
77
+ def mathmlsymbolwrap(units, normalise)
78
+ <<~END
79
+ <math xmlns='#{MATHML_NS}'><mrow>#{mathmlsymbol(units, normalise)}</mrow></math>
80
+ END
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,81 @@
1
+ module Asciimath2UnitsML
2
+ class Conv
3
+ def units_only(units)
4
+ units.reject { |u| u[:multiplier] }
5
+ end
6
+
7
+ def unit_id(text)
8
+ text = text.gsub(/[()]/, "")
9
+ /-$/.match(text) and return @prefixes[text.sub(/-$/, "")].id
10
+ "U_" + (@units[text] ? @units[text].id.gsub(/'/, "_") : text.gsub(/\*/, ".").gsub(/\^/, ""))
11
+ end
12
+
13
+ def unit(units, origtext, normtext, dims, name)
14
+ return if units_only(units).any? { |x| x[:unit].nil? }
15
+ dimid = dim_id(dims)
16
+ norm_units = normalise_units(units)
17
+ <<~END
18
+ <Unit xmlns='#{UNITSML_NS}' xml:id='#{unit_id(normtext)}'#{dimid ? " dimensionURL='##{dimid}'" : ""}>
19
+ #{unitsystem(units)}
20
+ #{unitname(norm_units, normtext, name)}
21
+ #{unitsymbol(norm_units)}
22
+ #{rootunits(units)}
23
+ </Unit>
24
+ END
25
+ end
26
+
27
+ def normalise_units(units)
28
+ units.map do |u|
29
+ u1 = u.dup
30
+ u1[:multiplier] and u1[:multiplier] = "*"
31
+ u1[:exponent] and u1[:display_exponent] = u1[:exponent]
32
+ u1
33
+ end
34
+ end
35
+
36
+ # kg exception
37
+ def unitsystem(units)
38
+ return if units_only(units).any? { |x| x[:unit].nil? }
39
+ ret = []
40
+ units = units_only(units)
41
+ units.any? { |x| @units[x[:unit]].system_name != "SI" } and
42
+ ret << "<UnitSystem name='not_SI' type='not_SI' xml:lang='en-US'/>"
43
+ if units.any? { |x| @units[x[:unit]].system_name == "SI" }
44
+ base = units.size == 1 && @units[units[0][:unit]].system_type == "SI-base"
45
+ base = true if units.size == 1 && units[0][:unit] == "g" && units[0][:prefix] == "k"
46
+ ret << "<UnitSystem name='SI' type='#{base ? "SI_base" : "SI_derived"}' xml:lang='en-US'/>"
47
+ end
48
+ ret.join("\n")
49
+ end
50
+
51
+ def unitname(units, text, name)
52
+ name ||= @units[text] ? @units[text].name : compose_name(units, text)
53
+ "<UnitName xml:lang='en'>#{name}</UnitName>"
54
+ end
55
+
56
+ # TODO: compose name from the component units
57
+ def compose_name(units, text)
58
+ text
59
+ end
60
+
61
+ def unitsymbol(units)
62
+ <<~END
63
+ <UnitSymbol type="HTML">#{htmlsymbol(units, true)}</UnitSymbol>
64
+ <UnitSymbol type="MathML">#{mathmlsymbolwrap(units, true)}</UnitSymbol>
65
+ END
66
+ end
67
+
68
+ def rootunits(units)
69
+ return if units_only(units).any? { |x| x[:unit].nil? }
70
+ return if units.size == 1 && !units[0][:prefix]
71
+ exp = units_only(units).map do |u|
72
+ prefix = " prefix='#{u[:prefix]}'" if u[:prefix]
73
+ exponent = " powerNumerator='#{u[:exponent]}'" if u[:exponent] && u[:exponent] != "1"
74
+ "<EnumeratedRootUnit unit='#{@units[u[:unit]].name}'#{prefix}#{exponent}/>"
75
+ end.join("\n")
76
+ <<~END
77
+ <RootUnits>#{exp}</RootUnits>
78
+ END
79
+ end
80
+ end
81
+ end
@@ -1,3 +1,3 @@
1
1
  module Asciimath2UnitsML
2
- VERSION = '0.1.3'.freeze
2
+ VERSION = '0.2.4'.freeze
3
3
  end
@@ -0,0 +1,802 @@
1
+ ---
2
+ NISTd1:
3
+ length:
4
+ powerNumerator: 1
5
+ symbol: L
6
+
7
+ NISTd2:
8
+ mass:
9
+ powerNumerator: 1
10
+ symbol: M
11
+
12
+ NISTd3:
13
+ time:
14
+ powerNumerator: 1
15
+ symbol: T
16
+
17
+ NISTd4:
18
+ electric_current:
19
+ powerNumerator: 1
20
+ symbol: I
21
+
22
+ NISTd5:
23
+ thermodynamic_temperature:
24
+ powerNumerator: 1
25
+ symbol:
26
+
27
+ NISTd6:
28
+ amount_of_substance:
29
+ powerNumerator: 1
30
+ symbol: N
31
+
32
+ NISTd7:
33
+ luminous_intensity:
34
+ powerNumerator: 1
35
+ symbol: J
36
+
37
+ NISTd8:
38
+ length:
39
+ powerNumerator: 2
40
+ symbol: L
41
+
42
+ NISTd9:
43
+ dimensionless: true
44
+ plane_angle:
45
+ powerNumerator: 1
46
+ symbol: phi
47
+
48
+ NISTd10:
49
+ length:
50
+ powerNumerator: 3
51
+ symbol: L
52
+
53
+ NISTd11:
54
+ length:
55
+ powerNumerator: 1
56
+ symbol: L
57
+ time:
58
+ powerNumerator: -1
59
+ symbol: T
60
+
61
+ NISTd12:
62
+ length:
63
+ powerNumerator: 1
64
+ symbol: L
65
+ mass:
66
+ powerNumerator: 1
67
+ symbol: M
68
+ time:
69
+ powerNumerator: -2
70
+ symbol: T
71
+
72
+ NISTd13:
73
+ mass:
74
+ powerNumerator: 1
75
+ symbol: M
76
+ time:
77
+ powerNumerator: -2
78
+ symbol: T
79
+ electric_current:
80
+ powerNumerator: -1
81
+ symbol: I
82
+
83
+ NISTd14:
84
+ length:
85
+ powerNumerator: -1
86
+ symbol: L
87
+ mass:
88
+ powerNumerator: 1
89
+ symbol: M
90
+ time:
91
+ powerNumerator: -2
92
+ symbol: T
93
+
94
+ NISTd15:
95
+ length:
96
+ powerNumerator: 2
97
+ symbol: L
98
+ mass:
99
+ powerNumerator: 1
100
+ symbol: M
101
+ time:
102
+ powerNumerator: -2
103
+ symbol: T
104
+
105
+ NISTd17:
106
+ time:
107
+ powerNumerator: 1
108
+ symbol: T
109
+ electric_current:
110
+ powerNumerator: 1
111
+ symbol: I
112
+
113
+ NISTd16:
114
+ length:
115
+ powerNumerator: 2
116
+ symbol: L
117
+ mass:
118
+ powerNumerator: 1
119
+ symbol: M
120
+ time:
121
+ powerNumerator: -3
122
+ symbol: T
123
+
124
+ NISTd19:
125
+ length:
126
+ powerNumerator: -2
127
+ symbol: L
128
+ mass:
129
+ powerNumerator: -1
130
+ symbol: M
131
+ time:
132
+ powerNumerator: 4
133
+ symbol: T
134
+ electric_current:
135
+ powerNumerator: 2
136
+ symbol: I
137
+
138
+ NISTd18:
139
+ length:
140
+ powerNumerator: 2
141
+ symbol: L
142
+ mass:
143
+ powerNumerator: 1
144
+ symbol: M
145
+ time:
146
+ powerNumerator: -3
147
+ symbol: T
148
+ electric_current:
149
+ powerNumerator: -1
150
+ symbol: I
151
+
152
+ NISTd21:
153
+ length:
154
+ powerNumerator: -2
155
+ symbol: L
156
+ mass:
157
+ powerNumerator: -1
158
+ symbol: M
159
+ time:
160
+ powerNumerator: 3
161
+ symbol: T
162
+ electric_current:
163
+ powerNumerator: 2
164
+ symbol: I
165
+
166
+ NISTd20:
167
+ length:
168
+ powerNumerator: 2
169
+ symbol: L
170
+ mass:
171
+ powerNumerator: 1
172
+ symbol: M
173
+ time:
174
+ powerNumerator: -3
175
+ symbol: T
176
+ electric_current:
177
+ powerNumerator: -2
178
+ symbol: I
179
+
180
+ NISTd23:
181
+ length:
182
+ powerNumerator: 2
183
+ symbol: L
184
+ mass:
185
+ powerNumerator: 1
186
+ symbol: M
187
+ time:
188
+ powerNumerator: -2
189
+ symbol: T
190
+ electric_current:
191
+ powerNumerator: -2
192
+ symbol: I
193
+
194
+ NISTd22:
195
+ length:
196
+ powerNumerator: 2
197
+ symbol: L
198
+ mass:
199
+ powerNumerator: 1
200
+ symbol: M
201
+ time:
202
+ powerNumerator: -2
203
+ symbol: T
204
+ electric_current:
205
+ powerNumerator: -1
206
+ symbol: I
207
+
208
+ NISTd25:
209
+ length:
210
+ powerNumerator: 2
211
+ symbol: L
212
+ time:
213
+ powerNumerator: -2
214
+ symbol: T
215
+
216
+ NISTd24:
217
+ time:
218
+ powerNumerator: -1
219
+ symbol: T
220
+
221
+ NISTd27:
222
+ length:
223
+ powerNumerator: -2
224
+ symbol: L
225
+ luminous_intensity:
226
+ powerNumerator: 1
227
+ symbol: J
228
+
229
+ NISTd26:
230
+ time:
231
+ powerNumerator: -1
232
+ symbol: T
233
+ amount_of_substance:
234
+ powerNumerator: 1
235
+ symbol: N
236
+
237
+ NISTd29:
238
+ length:
239
+ powerNumerator: -1
240
+ symbol: L
241
+
242
+ NISTd28:
243
+ length:
244
+ powerNumerator: 1
245
+ symbol: L
246
+ time:
247
+ powerNumerator: -2
248
+ symbol: T
249
+
250
+ NISTd31:
251
+ length:
252
+ powerNumerator: 3
253
+ symbol: L
254
+ mass:
255
+ powerNumerator: -1
256
+ symbol: M
257
+
258
+ NISTd30:
259
+ length:
260
+ powerNumerator: -3
261
+ symbol: L
262
+ mass:
263
+ powerNumerator: 1
264
+ symbol: M
265
+
266
+ NISTd34:
267
+ length:
268
+ powerNumerator: -3
269
+ symbol: L
270
+ amount_of_substance:
271
+ powerNumerator: 1
272
+ symbol: N
273
+
274
+ NISTd35:
275
+ time:
276
+ powerNumerator: -2
277
+ symbol: T
278
+
279
+ NISTd32:
280
+ length:
281
+ powerNumerator: -2
282
+ symbol: L
283
+ electric_current:
284
+ powerNumerator: 1
285
+ symbol: I
286
+
287
+ NISTd33:
288
+ length:
289
+ powerNumerator: -1
290
+ symbol: L
291
+ electric_current:
292
+ powerNumerator: 1
293
+ symbol: I
294
+
295
+ NISTd38:
296
+ mass:
297
+ powerNumerator: 1
298
+ symbol: M
299
+ time:
300
+ powerNumerator: -3
301
+ symbol: T
302
+
303
+ NISTd39:
304
+ length:
305
+ powerNumerator: 2
306
+ symbol: L
307
+ mass:
308
+ powerNumerator: 1
309
+ symbol: M
310
+ time:
311
+ powerNumerator: -2
312
+ symbol: T
313
+ thermodynamic_temperature:
314
+ powerNumerator: -1
315
+ symbol:
316
+
317
+ NISTd36:
318
+ length:
319
+ powerNumerator: -1
320
+ symbol: L
321
+ mass:
322
+ powerNumerator: 1
323
+ symbol: M
324
+ time:
325
+ powerNumerator: -1
326
+ symbol: T
327
+
328
+ NISTd37:
329
+ mass:
330
+ powerNumerator: 1
331
+ symbol: M
332
+ time:
333
+ powerNumerator: -2
334
+ symbol: T
335
+
336
+ NISTd42:
337
+ length:
338
+ powerNumerator: 1
339
+ symbol: L
340
+ mass:
341
+ powerNumerator: 1
342
+ symbol: M
343
+ time:
344
+ powerNumerator: -3
345
+ symbol: T
346
+ electric_current:
347
+ powerNumerator: -1
348
+ symbol: I
349
+
350
+ NISTd43:
351
+ length:
352
+ powerNumerator: -3
353
+ symbol: L
354
+ time:
355
+ powerNumerator: 1
356
+ symbol: T
357
+ electric_current:
358
+ powerNumerator: 1
359
+ symbol: I
360
+
361
+ NISTd40:
362
+ length:
363
+ powerNumerator: 2
364
+ symbol: L
365
+ time:
366
+ powerNumerator: -2
367
+ symbol: T
368
+ thermodynamic_temperature:
369
+ powerNumerator: -1
370
+ symbol:
371
+
372
+ NISTd41:
373
+ length:
374
+ powerNumerator: 1
375
+ symbol: L
376
+ mass:
377
+ powerNumerator: 1
378
+ symbol: M
379
+ time:
380
+ powerNumerator: -3
381
+ symbol: T
382
+ thermodynamic_temperature:
383
+ powerNumerator: -1
384
+ symbol:
385
+
386
+ NISTd46:
387
+ length:
388
+ powerNumerator: 1
389
+ symbol: L
390
+ mass:
391
+ powerNumerator: 1
392
+ symbol: M
393
+ time:
394
+ powerNumerator: -2
395
+ symbol: T
396
+ electric_current:
397
+ powerNumerator: -2
398
+ symbol: I
399
+
400
+ NISTd47:
401
+ length:
402
+ powerNumerator: 2
403
+ symbol: L
404
+ mass:
405
+ powerNumerator: 1
406
+ symbol: M
407
+ time:
408
+ powerNumerator: -2
409
+ symbol: T
410
+ amount_of_substance:
411
+ powerNumerator: -1
412
+ symbol: N
413
+
414
+ NISTd44:
415
+ length:
416
+ powerNumerator: -2
417
+ symbol: L
418
+ time:
419
+ powerNumerator: 1
420
+ symbol: T
421
+ electric_current:
422
+ powerNumerator: 1
423
+ symbol: I
424
+
425
+ NISTd45:
426
+ length:
427
+ powerNumerator: -3
428
+ symbol: L
429
+ mass:
430
+ powerNumerator: -1
431
+ symbol: M
432
+ time:
433
+ powerNumerator: 4
434
+ symbol: T
435
+ electric_current:
436
+ powerNumerator: 2
437
+ symbol: I
438
+
439
+ NISTd51:
440
+ length:
441
+ powerNumerator: -2
442
+ symbol: L
443
+ mass:
444
+ powerNumerator: 1
445
+ symbol: M
446
+
447
+ NISTd50:
448
+ length:
449
+ powerNumerator: 2
450
+ symbol: L
451
+ time:
452
+ powerNumerator: -3
453
+ symbol: T
454
+
455
+ NISTd49:
456
+ mass:
457
+ powerNumerator: -1
458
+ symbol: M
459
+ time:
460
+ powerNumerator: 1
461
+ symbol: T
462
+ electric_current:
463
+ powerNumerator: 1
464
+ symbol: I
465
+
466
+ NISTd48:
467
+ length:
468
+ powerNumerator: 2
469
+ symbol: L
470
+ mass:
471
+ powerNumerator: 1
472
+ symbol: M
473
+ time:
474
+ powerNumerator: -2
475
+ symbol: T
476
+ thermodynamic_temperature:
477
+ powerNumerator: -1
478
+ symbol:
479
+ amount_of_substance:
480
+ powerNumerator: -1
481
+ symbol: N
482
+
483
+ NISTd55:
484
+ mass:
485
+ powerNumerator: -3
486
+ symbol: M
487
+ time:
488
+ powerNumerator: -1
489
+ symbol: T
490
+ amount_of_substance:
491
+ powerNumerator: 1
492
+ symbol: N
493
+
494
+ NISTd54:
495
+ length:
496
+ powerNumerator: 2
497
+ symbol: L
498
+ mass:
499
+ powerNumerator: 1
500
+ symbol: M
501
+ time:
502
+ powerNumerator: 2
503
+ symbol: T
504
+ electric_current:
505
+ powerNumerator: 2
506
+ symbol: I
507
+
508
+ NISTd53:
509
+ mass:
510
+ powerNumerator: -2
511
+ symbol: M
512
+ time:
513
+ powerNumerator: 1
514
+ symbol: T
515
+ electric_current:
516
+ powerNumerator: 1
517
+ symbol: I
518
+
519
+ NISTd52:
520
+ length:
521
+ powerNumerator: 1
522
+ symbol: L
523
+ mass:
524
+ powerNumerator: -1
525
+ symbol: M
526
+ time:
527
+ powerNumerator: 1
528
+ symbol: T
529
+
530
+ NISTd59:
531
+ length:
532
+ powerNumerator: 2
533
+ symbol: L
534
+ mass:
535
+ powerNumerator: 1
536
+ symbol: M
537
+
538
+ NISTd58:
539
+ length:
540
+ powerNumerator: -1
541
+ symbol: L
542
+ mass:
543
+ powerNumerator: 1
544
+ symbol: M
545
+
546
+ NISTd57:
547
+ length:
548
+ powerNumerator: 4
549
+ symbol: L
550
+
551
+ NISTd56:
552
+ length:
553
+ powerNumerator: 2
554
+ symbol: L
555
+ time:
556
+ powerNumerator: -1
557
+ symbol: T
558
+
559
+ NISTd63:
560
+ length:
561
+ powerNumerator: 1
562
+ symbol: L
563
+ mass:
564
+ powerNumerator: -1
565
+ symbol: M
566
+ time:
567
+ powerNumerator: 2
568
+ symbol: T
569
+
570
+ NISTd62:
571
+ length:
572
+ powerNumerator: 3
573
+ symbol: L
574
+ mass:
575
+ powerNumerator: -1
576
+ symbol: M
577
+ time:
578
+ powerNumerator: -2
579
+ symbol: T
580
+
581
+ NISTd61:
582
+ length:
583
+ powerNumerator: 1
584
+ symbol: L
585
+ mass:
586
+ powerNumerator: 1
587
+ symbol: M
588
+ time:
589
+ powerNumerator: -1
590
+ symbol: T
591
+
592
+ NISTd60:
593
+ length:
594
+ powerNumerator: 2
595
+ symbol: L
596
+ mass:
597
+ powerNumerator: 1
598
+ symbol: M
599
+ time:
600
+ powerNumerator: -1
601
+ symbol: T
602
+
603
+ NISTd68:
604
+ thermodynamic_temperature:
605
+ powerNumerator: -1
606
+ symbol:
607
+
608
+ NISTd69:
609
+ length:
610
+ powerNumerator: -1
611
+ symbol: L
612
+ mass:
613
+ powerNumerator: 1
614
+ symbol: M
615
+ time:
616
+ powerNumerator: -2
617
+ symbol: T
618
+ thermodynamic_temperature:
619
+ powerNumerator: -1
620
+ symbol:
621
+
622
+ NISTd70:
623
+ length:
624
+ powerNumerator: 1
625
+ symbol: L
626
+ mass:
627
+ powerNumerator: -1
628
+ symbol: M
629
+ time:
630
+ powerNumerator: 2
631
+ symbol: T
632
+
633
+ NISTd71:
634
+ mass:
635
+ powerNumerator: 1
636
+ symbol: M
637
+ time:
638
+ powerNumerator: -3
639
+ symbol: T
640
+ thermodynamic_temperature:
641
+ powerNumerator: -1
642
+ symbol:
643
+
644
+ NISTd64:
645
+ dimensionless: true
646
+ plane_angle:
647
+ powerNumerator: 1
648
+ symbol: phi
649
+
650
+ NISTd65:
651
+ mass:
652
+ powerNumerator: 1
653
+ symbol: M
654
+ time:
655
+ powerNumerator: -1
656
+ symbol: T
657
+
658
+ NISTd66:
659
+ length:
660
+ powerNumerator: 3
661
+ symbol: L
662
+ time:
663
+ powerNumerator: -1
664
+ symbol: T
665
+
666
+ NISTd67:
667
+ dimensionless: true
668
+ NISTd76:
669
+ mass:
670
+ powerNumerator: 1
671
+ symbol: M
672
+ time:
673
+ powerNumerator: 4
674
+ symbol: T
675
+ electric_current:
676
+ powerNumerator: 2
677
+ symbol: I
678
+
679
+ NISTd77:
680
+ length:
681
+ powerNumerator: -1
682
+ symbol: L
683
+ mass:
684
+ powerNumerator: -2
685
+ symbol: M
686
+ time:
687
+ powerNumerator: 7
688
+ symbol: T
689
+ electric_current:
690
+ powerNumerator: 3
691
+ symbol: I
692
+
693
+ NISTd78:
694
+ length:
695
+ powerNumerator: -2
696
+ symbol: L
697
+ mass:
698
+ powerNumerator: -3
699
+ symbol: M
700
+ time:
701
+ powerNumerator: 10
702
+ symbol: T
703
+ electric_current:
704
+ powerNumerator: 4
705
+ symbol: I
706
+
707
+ NISTd79:
708
+ mass:
709
+ powerNumerator: 1
710
+ symbol: M
711
+ amount_of_substance:
712
+ powerNumerator: 1
713
+ symbol: N
714
+
715
+ NISTd72:
716
+ length:
717
+ powerNumerator: 1
718
+ symbol: L
719
+ time:
720
+ powerNumerator: 1
721
+ symbol: T
722
+ electric_current:
723
+ powerNumerator: 1
724
+ symbol: I
725
+
726
+ NISTd73:
727
+ length:
728
+ powerNumerator: 2
729
+ symbol: L
730
+ electric_current:
731
+ powerNumerator: 1
732
+ symbol: I
733
+
734
+ NISTd74:
735
+ mass:
736
+ powerNumerator: 1
737
+ symbol: M
738
+ time:
739
+ powerNumerator: -3
740
+ symbol: T
741
+ electric_current:
742
+ powerNumerator: -1
743
+ symbol: I
744
+
745
+ NISTd75:
746
+ length:
747
+ powerNumerator: 2
748
+ symbol: L
749
+ time:
750
+ powerNumerator: 1
751
+ symbol: T
752
+ electric_current:
753
+ powerNumerator: 1
754
+ symbol: I
755
+
756
+ #NISTd85:
757
+ #dimensionless: true
758
+
759
+ #NISTd84:
760
+ #dimensionless: true
761
+
762
+ #NISTd87:
763
+ #dimensionless: true
764
+
765
+ #NISTd86:
766
+ #dimensionless: true
767
+
768
+ #NISTd81:
769
+ #dimensionless: true
770
+
771
+ NISTd80:
772
+ dimensionless: true
773
+
774
+ #NISTd83:
775
+ #dimensionless: true
776
+
777
+ #NISTd82:
778
+ #dimensionless: true
779
+
780
+ #NISTd95:
781
+ #dimensionless: true
782
+
783
+ #NISTd94:
784
+ #dimensionless: true
785
+
786
+ #NISTd89:
787
+ #dimensionless: true
788
+
789
+ #NISTd88:
790
+ #dimensionless: true
791
+
792
+ #NISTd91:
793
+ #dimensionless: true
794
+
795
+ #NISTd90:
796
+ #dimensionless: true
797
+
798
+ #NISTd92:
799
+ #dimensionless: true
800
+
801
+ #NISTd93:
802
+ #dimensionless: true