asciimath2unitsml 0.1.1 → 0.2.2

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,39 +84,64 @@ 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
+ @units[k].root&.any? { |x| x[:prefix] } || /\*|\^|\/|^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
- exponent = /\^-?\d+/.r.map { |m| m.sub(/\^/, "") }
41
- multiplier = /\*/.r
42
- unit = seq(unit1, exponent._?) { |x| { prefix: nil, unit: x[0], exponent: x[1][0] } } |
43
- seq(prefix, unit1, exponent._?) { |x| { prefix: x[0][0], unit: x[1], exponent: x[2][0] } }
44
- units_tail = seq(multiplier, unit) { |u| u[1] }
45
- units = seq(unit, units_tail.star) { |x| [x[0], x[1]].flatten }
93
+ exponent = /\^\(-?\d+\)/.r.map { |m| m.sub(/\^/, "").gsub(/[()]/, "") } |
94
+ /\^-?\d+/.r.map { |m| m.sub(/\^/, "") }
95
+ multiplier = %r{\*|//|/}.r.map { |x| { multiplier: x[0] } }
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)
46
108
  parser = units.eof
47
109
  end
48
110
 
49
111
  def parse(x)
50
- units = @parser.parse(x)
112
+ text = Array(x.split(/,\s*/))
113
+ units = @parser.parse!(text[0])
51
114
  if !units || Rsec::INVALID[units]
52
115
  raise Rsec::SyntaxError.new "error parsing UnitsML expression", x, 1, 0
53
116
  end
54
117
  Rsec::Fail.reset
55
- units
118
+ postprocess(units, text)
119
+ end
120
+
121
+ def postprocess(units, text)
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*/, "")
126
+ normtext = units_only(units).each.map do |u|
127
+ exp = u[:exponent] && u[:exponent] != "1" ? "^#{u[:exponent]}" : ""
128
+ "#{u[:prefix]}#{u[:unit]}#{exp}"
129
+ end.join("*")
130
+ [units, text[0], normtext, quantity, name, symbol]
56
131
  end
57
132
 
58
- U2D = {
59
- "m" => { dimension: "Length", order: 1, symbol: "L" },
60
- "g" => { dimension: "Mass", order: 2, symbol: "M" },
61
- "kg" => { dimension: "Mass", order: 2, symbol: "M" },
62
- "s" => { dimension: "Time", order: 3, symbol: "T" },
63
- "A" => { dimension: "ElectricCurrent", order: 4, symbol: "I" },
64
- "K" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" },
65
- "mol" => { dimension: "AmountOfSubstance", order: 6, symbol: "N" },
66
- "cd" => { dimension: "LuminousIntensity", order: 7, symbol: "J" },
67
- }
133
+ def postprocess1(units)
134
+ inverse = false
135
+ units.each_with_object([]) do |u, m|
136
+ if u[:multiplier]
137
+ inverse = (u[:multiplier] == "/")
138
+ else
139
+ u[:exponent] = inverse ? "-#{u[:display_exponent] || '1'}" : u[:display_exponent]
140
+ u[:exponent] = u[:exponent]&.sub(/^--+/, "")
141
+ end
142
+ m << u
143
+ end
144
+ end
68
145
 
69
146
  def Asciimath2UnitsML(expression)
70
147
  xml = Nokogiri::XML(asciimath2mathml(expression))
@@ -73,12 +150,33 @@ module Asciimath2UnitsML
73
150
 
74
151
  # https://www.w3.org/TR/mathml-units/ section 2: delimit number Invisible-Times unit
75
152
  def MathML2UnitsML(xml)
153
+ xml.is_a? String and xml = Nokogiri::XML(xml)
76
154
  xml.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
77
155
  next unless %r{^unitsml\(.+\)$}.match(x.text)
78
156
  text = x.text.sub(%r{^unitsml\((.+)\)$}m, "\\1")
79
- units = parse(text)
80
- delim = x&.previous_element&.name == "mn" ? "<mo rspace='thickmathspace'>&#x2062;</mo>" : ""
81
- x.replace("#{delim}<mrow xref='#{unit_id(text)}'>#{mathmlsymbol(units)}</mrow>\n#{unitsml(units, text)}")
157
+ units, origtext, normtext, quantity, name, symbol = parse(text)
158
+ rendering = symbol ? embeddedmathml(asciimath2mathml(symbol)) : mathmlsymbol(units, false)
159
+ delim = x&.previous_element ? delimspace(rendering) : ""
160
+ x.replace("#{delim}<mrow xref='#{unit_id(origtext)}'>#{rendering}</mrow>\n"\
161
+ "#{unitsml(units, origtext, normtext, quantity, name)}")
162
+ end
163
+ dedup_ids(xml)
164
+ end
165
+
166
+ def delimspace(x)
167
+ text = HTMLEntities.new.encode(Nokogiri::XML("<mrow>#{x}</mrow>").text.strip)
168
+ /[[:alnum:]]/.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
82
180
  end
83
181
  xml
84
182
  end
@@ -88,5 +186,43 @@ module Asciimath2UnitsML
88
186
  AsciiMath.parse(HTMLEntities.new.decode(expression)).ast).to_s.
89
187
  gsub(/<math>/, "<math xmlns='#{MATHML_NS}'>")
90
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
91
227
  end
92
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.1'.freeze
2
+ VERSION = '0.2.2'.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