asciimath2unitsml 0.1.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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