asciimath2unitsml 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,163 @@
1
+ module UnitsDB
2
+ class Dimension
3
+ attr_reader :id, :length, :mass, :time, :electric_current, :thermodynamic_temperature,
4
+ :amount_of_substance, :luminous_intensity, :plane_angle, :dimensionless
5
+
6
+ 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}"
21
+ end
22
+ end
23
+
24
+ def keys
25
+ ret = []
26
+ @length and ret << "Length"
27
+ @mass and ret << "Mass"
28
+ @time and ret << "Time"
29
+ @electric_current and ret << "ElectricCurrent"
30
+ @thermodynamic_temperature and ret << "ThermodynamicTemperature"
31
+ @amount_of_substance and ret << "AmountOfSubstance"
32
+ @luminous_intensity and ret << "LuminousIntensity"
33
+ @plane_angle and ret << "PlaneAngle"
34
+ ret
35
+ end
36
+
37
+ def exponent(key)
38
+ case key
39
+ when "Length" then @length
40
+ when "Mass" then @mass
41
+ when "Time" then @time
42
+ when "ElectricCurrent" then @electric_current
43
+ when "ThermodynamicTemperature" then @thermodynamic_temperature
44
+ when "AmountOfSubstance" then @amount_of_substance
45
+ when "LuminousIntensity" then @luminous_intensity
46
+ when "PlaneAngle" then @plane_angle
47
+ end
48
+ end
49
+
50
+ def vector
51
+ "#{@length}:#{@mass}:#{@time}:#{@electric_current}:#{@thermodynamic_temperature}:#{@amount_of_substance}:"\
52
+ "#{@luminous_intensity}:#{@plane_angle}"
53
+ end
54
+ end
55
+
56
+ class Prefix
57
+ attr_reader :id, :name, :base, :power, :symbol
58
+
59
+ 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
69
+ end
70
+
71
+ def ascii
72
+ @symbol[:ascii]
73
+ end
74
+
75
+ def symbolid
76
+ @symbol[:ascii]
77
+ end
78
+
79
+ def html
80
+ @symbol[:html]
81
+ end
82
+
83
+ def mathml
84
+ @symbol[:html]
85
+ end
86
+
87
+ def latex
88
+ @symbol[:latex]
89
+ end
90
+
91
+ def unicode
92
+ @symbol[:unicode]
93
+ end
94
+ end
95
+
96
+ class Quantity
97
+ attr_reader :id, :dimension, :type, :names, :units
98
+
99
+ 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
109
+ end
110
+
111
+ def name
112
+ @names&.first
113
+ end
114
+
115
+ def unit
116
+ @units&.first
117
+ end
118
+ end
119
+
120
+ class Unit
121
+ attr_reader :id, :dimension, :short, :root, :unit_system, :names, :symbols, :symbols_hash, :root_units, :quantities,
122
+ :si_derived_bases, :prefixed
123
+
124
+ 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
+ rescue
139
+ raise StandardError.new "Parse fail on Unit #{id}: #{hash}"
140
+ end
141
+ end
142
+
143
+ def system_name
144
+ @unit_system[:name]
145
+ end
146
+
147
+ def system_type
148
+ @unit_system[:type]
149
+ end
150
+
151
+ def name
152
+ @names.first
153
+ end
154
+
155
+ def symbolid
156
+ @symbols ? @symbols.first[:id] : @short
157
+ end
158
+
159
+ def symbolids
160
+ @symbols ? @symbols.map { |s| s[:id] } : [ @short ]
161
+ end
162
+ end
163
+ end
data/spec/conv_spec.rb CHANGED
@@ -3,19 +3,18 @@ require "spec_helper"
3
3
  RSpec.describe Asciimath2UnitsML do
4
4
  it "converts an AsciiMath string to MathML + UnitsML" do
5
5
  expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
6
- 32 + 5 xx 7 "unitsml(kg^-2)" xx 9 "unitsml(g)" xx 1 "unitsml(kg*s^-2)" xx 812 "unitsml(m*s^-2)" - 9 "unitsml(C^3*A)" + 7 "unitsml(hp)"
6
+ 1 "unitsml(mm*s^-2)"
7
7
  INPUT
8
- <math xmlns='http://www.w3.org/1998/Math/MathML'>
9
- <mn>32</mn>
10
- <mo>+</mo>
11
- <mn>5</mn>
12
- <mo>&#xD7;</mo>
13
- <mn>7</mn>
8
+ <?xml version='1.0'?>
9
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
10
+ <mn>1</mn>
14
11
  <mo rspace='thickmathspace'>&#x2062;</mo>
15
- <mrow xref='U_kg-2'>
12
+ <mrow xref='U_mm.s-2'>
13
+ <mi mathvariant='normal'>mm</mi>
14
+ <mo>&#xB7;</mo>
16
15
  <msup>
17
16
  <mrow>
18
- <mi mathvariant='normal'>kg</mi>
17
+ <mi mathvariant='normal'>s</mi>
19
18
  </mrow>
20
19
  <mrow>
21
20
  <mo>&#x2212;</mo>
@@ -23,19 +22,21 @@ RSpec.describe Asciimath2UnitsML do
23
22
  </mrow>
24
23
  </msup>
25
24
  </mrow>
26
- <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg-2' dimensionURL='#D_M-2'>
27
- <UnitSystem name='SI' type='SI_base' xml:lang='en-US'/>
28
- <UnitName xml:lang='en'>kg^-2</UnitName>
25
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_mm.s-2' dimensionURL='#NISTd28'>
26
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
27
+ <UnitName xml:lang='en'>mm*s^-2</UnitName>
29
28
  <UnitSymbol type='HTML'>
30
- kg
29
+ mm&#xB7;s
31
30
  <sup>&#x2212;2</sup>
32
31
  </UnitSymbol>
33
32
  <UnitSymbol type='MathML'>
34
33
  <math xmlns='http://www.w3.org/1998/Math/MathML'>
35
34
  <mrow>
35
+ <mi mathvariant='normal'>mm</mi>
36
+ <mo>&#xB7;</mo>
36
37
  <msup>
37
38
  <mrow>
38
- <mi mathvariant='normal'>kg</mi>
39
+ <mi mathvariant='normal'>s</mi>
39
40
  </mrow>
40
41
  <mrow>
41
42
  <mo>&#x2212;</mo>
@@ -45,22 +46,202 @@ RSpec.describe Asciimath2UnitsML do
45
46
  </mrow>
46
47
  </math>
47
48
  </UnitSymbol>
49
+ <RootUnits>
50
+ <EnumeratedRootUnit unit='meter' prefix='m'/>
51
+ <EnumeratedRootUnit unit='second' powerNumerator='-2'/>
52
+ </RootUnits>
53
+ </Unit>
54
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='-3' xml:id='NISTp10_-3'>
55
+ <PrefixName xml:lang='en'>milli</PrefixName>
56
+ <PrefixSymbol type='ASCII'>m</PrefixSymbol>
57
+ <PrefixSymbol type='unicode'>m</PrefixSymbol>
58
+ <PrefixSymbol type='LaTeX'>m</PrefixSymbol>
59
+ <PrefixSymbol type='HTML'>m</PrefixSymbol>
60
+ </Prefix>
61
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd28'>
62
+ <Length symbol='L' powerNumerator='1'/>
63
+ <Time symbol='T' powerNumerator='-2'/>
64
+ </Dimension>
65
+ </math>
66
+ OUTPUT
67
+ end
68
+
69
+ it "deals with non-Ascii units and prefixes" do
70
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
71
+ 1 "unitsml(um)"
72
+ INPUT
73
+ <?xml version='1.0'?>
74
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
75
+ <mn>1</mn>
76
+ <mo rspace='thickmathspace'>&#x2062;</mo>
77
+ <mrow xref='U_um'>
78
+ <mi mathvariant='normal'>um</mi>
79
+ </mrow>
80
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_um' dimensionURL='#NISTd1'>
81
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
82
+ <UnitName xml:lang='en'>um</UnitName>
83
+ <UnitSymbol type='HTML'>um</UnitSymbol>
84
+ <UnitSymbol type='MathML'>
85
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
86
+ <mrow>
87
+ <mi mathvariant='normal'>um</mi>
88
+ </mrow>
89
+ </math>
90
+ </UnitSymbol>
91
+ <RootUnits>
92
+ <EnumeratedRootUnit unit='meter' prefix='u'/>
93
+ </RootUnits>
94
+ </Unit>
95
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='-6' xml:id='NISTp10_-6'>
96
+ <PrefixName xml:lang='en'>micro</PrefixName>
97
+ <PrefixSymbol type='ASCII'>u</PrefixSymbol>
98
+ <PrefixSymbol type='unicode'>&#x3BC;</PrefixSymbol>
99
+ <PrefixSymbol type='LaTeX'>$mu$</PrefixSymbol>
100
+ <PrefixSymbol type='HTML'>&amp;micro;</PrefixSymbol>
101
+ </Prefix>
102
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd1'>
103
+ <Length symbol='L' powerNumerator='1'/>
104
+ </Dimension>
105
+ </math>
106
+ OUTPUT
107
+ end
108
+
109
+ it "does not insert space before non-alphabetic units" do
110
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
111
+ 1 "unitsml(degK)" + 1 "unitsml(prime)"
112
+ INPUT
113
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
114
+ <mn>1</mn>
115
+ <mo rspace='thickmathspace'>&#x2062;</mo>
116
+ <mrow xref='U_NISTu5'>
117
+ <mi mathvariant='normal'>&#xB0;K</mi>
118
+ </mrow>
119
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu5' dimensionURL='#NISTd5'>
120
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
121
+ <UnitName xml:lang='en'>kelvin</UnitName>
122
+ <UnitSymbol type='HTML'>K</UnitSymbol>
123
+ <UnitSymbol type='MathML'>
124
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
125
+ <mrow>
126
+ <mi mathvariant='normal'>K</mi>
127
+ </mrow>
128
+ </math>
129
+ </UnitSymbol>
130
+ </Unit>
131
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd5'>
132
+ <ThermodynamicTemperature symbol='Theta' powerNumerator='1'/>
133
+ </Dimension>
134
+ <Quantity xmlns='http://unitsml.nist.gov/2005' xml:id='NISTq5' dimensionURL='#NISTd5' quantityType='base'>
135
+ <QuantityName xml:lang='en-US'>thermodynamic temperature</QuantityName>
136
+ </Quantity>
137
+ <mo>+</mo>
138
+ <mn>1</mn>
139
+ <mo>&#x2062;</mo>
140
+ <mrow xref='U_NISTu147'>
141
+ <mi mathvariant='normal'>&#x2032;</mi>
142
+ </mrow>
143
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu147'>
144
+ <UnitSystem name='not_SI' type='not_SI' xml:lang='en-US'/>
145
+ <UnitName xml:lang='en'>minute (minute of arc)</UnitName>
146
+ <UnitSymbol type='HTML'>&#x2032;</UnitSymbol>
147
+ <UnitSymbol type='MathML'>
148
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
149
+ <mrow>
150
+ <mi mathvariant='normal'>&#x2032;</mi>
151
+ </mrow>
152
+ </math>
153
+ </UnitSymbol>
154
+ </Unit>
155
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd9'>
156
+ <PlaneAngle symbol='Phi' powerNumerator='1'/>
157
+ </Dimension>
158
+ <Quantity xmlns='http://unitsml.nist.gov/2005' xml:id='NISTq9' dimensionURL='#NISTd9' quantityType='base'>
159
+ <QuantityName xml:lang='en-US'>plane angle</QuantityName>
160
+ <QuantityName xml:lang='en-US'>angle</QuantityName>
161
+ </Quantity>
162
+ </math>
163
+ OUTPUT
164
+ end
165
+
166
+ it "deals with sqrt units" do
167
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
168
+ 1 "unitsml(sqrt(Hz))"
169
+ INPUT
170
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
171
+ <mn>1</mn>
172
+ <mo rspace='thickmathspace'>&#x2062;</mo>
173
+ <mrow xref='U_sqrtHz'>
174
+ <msqrt>
175
+ <mi mathvariant='normal'>Hz</mi>
176
+ </msqrt>
177
+ </mrow>
178
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_Hz0.5' dimensionURL='#D_T-0.5'>
179
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
180
+ <UnitName xml:lang='en'>Hz^0.5</UnitName>
181
+ <UnitSymbol type='HTML'>&#x221A;Hz</UnitSymbol>
182
+ <UnitSymbol type='MathML'>
183
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
184
+ <mrow>
185
+ <msqrt>
186
+ <mi mathvariant='normal'>Hz</mi>
187
+ </msqrt>
188
+ </mrow>
189
+ </math>
190
+ </UnitSymbol>
191
+ </Unit>
192
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_T-0.5'>
193
+ <Time symbol='T' powerNumerator='-0.5'/>
194
+ </Dimension>
195
+ </math>
196
+ OUTPUT
197
+ end
198
+
199
+ it "deals with kg and g" do
200
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
201
+ 1 "unitsml(kg)" + 1 "unitsml(g)"
202
+ INPUT
203
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
204
+ <mn>1</mn>
205
+ <mo rspace='thickmathspace'>&#x2062;</mo>
206
+ <mrow xref='U_NISTu2'>
207
+ <mi mathvariant='normal'>kg</mi>
208
+ </mrow>
209
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu2' dimensionURL='#NISTd2'>
210
+ <UnitSystem name='SI' type='SI_base' xml:lang='en-US'/>
211
+ <UnitName xml:lang='en'>kilogram</UnitName>
212
+ <UnitSymbol type='HTML'>kg</UnitSymbol>
213
+ <UnitSymbol type='MathML'>
214
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
215
+ <mrow>
216
+ <mi mathvariant='normal'>kg</mi>
217
+ </mrow>
218
+ </math>
219
+ </UnitSymbol>
220
+ <RootUnits>
221
+ <EnumeratedRootUnit unit='gram' prefix='k'/>
222
+ </RootUnits>
48
223
  </Unit>
49
224
  <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='3' xml:id='NISTp10_3'>
50
225
  <PrefixName xml:lang='en'>kilo</PrefixName>
51
226
  <PrefixSymbol type='ASCII'>k</PrefixSymbol>
227
+ <PrefixSymbol type='unicode'>k</PrefixSymbol>
228
+ <PrefixSymbol type='LaTeX'>k</PrefixSymbol>
229
+ <PrefixSymbol type='HTML'>k</PrefixSymbol>
52
230
  </Prefix>
53
- <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_M-2'>
54
- <Mass symbol='M' powerNumerator='-2'/>
231
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd2'>
232
+ <Mass symbol='M' powerNumerator='1'/>
55
233
  </Dimension>
56
- <mo>&#xD7;</mo>
57
- <mn>9</mn>
234
+ <Quantity xmlns='http://unitsml.nist.gov/2005' xml:id='NISTq2' dimensionURL='#NISTd2' quantityType='base'>
235
+ <QuantityName xml:lang='en-US'>mass</QuantityName>
236
+ </Quantity>
237
+ <mo>+</mo>
238
+ <mn>1</mn>
58
239
  <mo rspace='thickmathspace'>&#x2062;</mo>
59
240
  <mrow xref='U_NISTu27'>
60
241
  <mi mathvariant='normal'>g</mi>
61
242
  </mrow>
62
- <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu27' dimensionURL='#D_M'>
63
- <UnitSystem name='SI' type='SI_base' xml:lang='en-US'/>
243
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu27' dimensionURL='#NISTd2'>
244
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
64
245
  <UnitName xml:lang='en'>gram</UnitName>
65
246
  <UnitSymbol type='HTML'>g</UnitSymbol>
66
247
  <UnitSymbol type='MathML'>
@@ -71,10 +252,49 @@ RSpec.describe Asciimath2UnitsML do
71
252
  </math>
72
253
  </UnitSymbol>
73
254
  </Unit>
74
- <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_M'>
75
- <Mass symbol='M' powerNumerator='1'/>
76
- </Dimension>
77
- <mo>&#xD7;</mo>
255
+ </math>
256
+ OUTPUT
257
+ end
258
+
259
+ it "deals with non-metric" do
260
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
261
+ 1 "unitsml(hp)"
262
+ INPUT
263
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
264
+ <mn>1</mn>
265
+ <mo rspace='thickmathspace'>&#x2062;</mo>
266
+ <mrow xref='U_NISTu284'>
267
+ <mi mathvariant='normal'>hp</mi>
268
+ </mrow>
269
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu284'>
270
+ <UnitSystem name='not_SI' type='not_SI' xml:lang='en-US'/>
271
+ <UnitName xml:lang='en'>horsepower</UnitName>
272
+ <UnitSymbol type='HTML'>hp</UnitSymbol>
273
+ <UnitSymbol type='MathML'>
274
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
275
+ <mrow>
276
+ <mi mathvariant='normal'>hp</mi>
277
+ </mrow>
278
+ </math>
279
+ </UnitSymbol>
280
+ </Unit>
281
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd16'>
282
+ <Length symbol='L' powerNumerator='2'/>
283
+ <Mass symbol='M' powerNumerator='1'/>
284
+ <Time symbol='T' powerNumerator='-3'/>
285
+ </Dimension>
286
+ <Quantity xmlns='http://unitsml.nist.gov/2005' xml:id='NISTq20' dimensionURL='#NISTd16' quantityType='base'>
287
+ <QuantityName xml:lang='en-US'>power</QuantityName>
288
+ </Quantity>
289
+ </math>
290
+ OUTPUT
291
+ end
292
+
293
+ it "deals with duplicate units" do
294
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
295
+ 1 "unitsml(kg*s^-2)" xx 9 "unitsml(kg*s^-2)"
296
+ INPUT
297
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
78
298
  <mn>1</mn>
79
299
  <mo rspace='thickmathspace'>&#x2062;</mo>
80
300
  <mrow xref='U_kg.s-2'>
@@ -90,7 +310,7 @@ RSpec.describe Asciimath2UnitsML do
90
310
  </mrow>
91
311
  </msup>
92
312
  </mrow>
93
- <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg.s-2' dimensionURL='#D_MT-2'>
313
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg.s-2' dimensionURL='#NISTd37'>
94
314
  <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
95
315
  <UnitName xml:lang='en'>kg*s^-2</UnitName>
96
316
  <UnitSymbol type='HTML'>
@@ -122,16 +342,19 @@ RSpec.describe Asciimath2UnitsML do
122
342
  <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='3' xml:id='NISTp10_3'>
123
343
  <PrefixName xml:lang='en'>kilo</PrefixName>
124
344
  <PrefixSymbol type='ASCII'>k</PrefixSymbol>
345
+ <PrefixSymbol type='unicode'>k</PrefixSymbol>
346
+ <PrefixSymbol type='LaTeX'>k</PrefixSymbol>
347
+ <PrefixSymbol type='HTML'>k</PrefixSymbol>
125
348
  </Prefix>
126
- <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_MT-2'>
349
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd37'>
127
350
  <Mass symbol='M' powerNumerator='1'/>
128
351
  <Time symbol='T' powerNumerator='-2'/>
129
352
  </Dimension>
130
353
  <mo>&#xD7;</mo>
131
- <mn>812</mn>
354
+ <mn>9</mn>
132
355
  <mo rspace='thickmathspace'>&#x2062;</mo>
133
- <mrow xref='U_NISTu1.u3e-2_1'>
134
- <mi mathvariant='normal'>m</mi>
356
+ <mrow xref='U_kg.s-2'>
357
+ <mi mathvariant='normal'>kg</mi>
135
358
  <mo>&#xB7;</mo>
136
359
  <msup>
137
360
  <mrow>
@@ -143,43 +366,128 @@ RSpec.describe Asciimath2UnitsML do
143
366
  </mrow>
144
367
  </msup>
145
368
  </mrow>
146
- <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu1.u3e-2_1' dimensionURL='#D_LT-2'>
147
- <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
148
- <UnitName xml:lang='en'>meter per second squared</UnitName>
149
- <UnitSymbol type='HTML'>
150
- m&#xB7;s
151
- <sup>&#x2212;2</sup>
152
- </UnitSymbol>
153
- <UnitSymbol type='MathML'>
154
- <math xmlns='http://www.w3.org/1998/Math/MathML'>
155
- <mrow>
156
- <mi mathvariant='normal'>m</mi>
157
- <mo>&#xB7;</mo>
158
- <msup>
159
- <mrow>
160
- <mi mathvariant='normal'>s</mi>
161
- </mrow>
162
- <mrow>
163
- <mo>&#x2212;</mo>
164
- <mn>2</mn>
165
- </mrow>
166
- </msup>
167
- </mrow>
168
- </math>
169
- </UnitSymbol>
170
- <RootUnits>
171
- <EnumeratedRootUnit unit='meter'/>
172
- <EnumeratedRootUnit unit='second' powerNumerator='-2'/>
173
- </RootUnits>
174
- </Unit>
175
- <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_LT-2'>
176
- <Length symbol='L' powerNumerator='1'/>
177
- <Time symbol='T' powerNumerator='-2'/>
178
- </Dimension>
179
- <mo>&#x2212;</mo>
369
+ </math>
370
+ OUTPUT
371
+ end
372
+
373
+ it "deals with notational variants" do
374
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
375
+ 9 "unitsml(degK)" + 10 "unitsml(K)"
376
+ INPUT
377
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
378
+ <mn>9</mn>
379
+ <mo rspace='thickmathspace'>&#x2062;</mo>
380
+ <mrow xref='U_NISTu5'>
381
+ <mi mathvariant='normal'>&#xB0;K</mi>
382
+ </mrow>
383
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu5' dimensionURL='#NISTd5'>
384
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
385
+ <UnitName xml:lang='en'>kelvin</UnitName>
386
+ <UnitSymbol type='HTML'>K</UnitSymbol>
387
+ <UnitSymbol type='MathML'>
388
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
389
+ <mrow>
390
+ <mi mathvariant='normal'>K</mi>
391
+ </mrow>
392
+ </math>
393
+ </UnitSymbol>
394
+ </Unit>
395
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd5'>
396
+ <ThermodynamicTemperature symbol='Theta' powerNumerator='1'/>
397
+ </Dimension>
398
+ <Quantity xmlns='http://unitsml.nist.gov/2005' xml:id='NISTq5' dimensionURL='#NISTd5' quantityType='base'>
399
+ <QuantityName xml:lang='en-US'>thermodynamic temperature</QuantityName>
400
+ </Quantity>
401
+ <mo>+</mo>
402
+ <mn>10</mn>
403
+ <mo rspace='thickmathspace'>&#x2062;</mo>
404
+ <mrow xref='U_NISTu5'>
405
+ <mi mathvariant='normal'>K</mi>
406
+ </mrow>
407
+ </math>
408
+ OUTPUT
409
+ end
410
+
411
+ it "deals with prefixed units" do
412
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
413
+ 9 "unitsml(mbar)"
414
+ INPUT
415
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
416
+ <mn>9</mn>
417
+ <mo rspace='thickmathspace'>&#x2062;</mo>
418
+ <mrow xref='U_NISTu362'>
419
+ <mi mathvariant='normal'>mbar</mi>
420
+ </mrow>
421
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu362'>
422
+ <UnitSystem name='not_SI' type='not_SI' xml:lang='en-US'/>
423
+ <UnitName xml:lang='en'>millibar</UnitName>
424
+ <UnitSymbol type='HTML'>mbar</UnitSymbol>
425
+ <UnitSymbol type='MathML'>
426
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
427
+ <mrow>
428
+ <mi mathvariant='normal'>mbar</mi>
429
+ </mrow>
430
+ </math>
431
+ </UnitSymbol>
432
+ <RootUnits>
433
+ <EnumeratedRootUnit unit='bar' prefix='m'/>
434
+ </RootUnits>
435
+ </Unit>
436
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='-3' xml:id='NISTp10_-3'>
437
+ <PrefixName xml:lang='en'>milli</PrefixName>
438
+ <PrefixSymbol type='ASCII'>m</PrefixSymbol>
439
+ <PrefixSymbol type='unicode'>m</PrefixSymbol>
440
+ <PrefixSymbol type='LaTeX'>m</PrefixSymbol>
441
+ <PrefixSymbol type='HTML'>m</PrefixSymbol>
442
+ </Prefix>
443
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd14'>
444
+ <Length symbol='L' powerNumerator='-1'/>
445
+ <Mass symbol='M' powerNumerator='1'/>
446
+ <Time symbol='T' powerNumerator='-2'/>
447
+ </Dimension>
448
+ </math>
449
+ OUTPUT
450
+ end
451
+
452
+ it "deals with standalone prefixes" do
453
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
454
+ "unitsml(p-)" "unitsml(da-)"
455
+ INPUT
456
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
457
+ <mrow xref='NISTp10_-12'>
458
+ <mi mathvariant='normal'>p</mi>
459
+ </mrow>
460
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='-12' xml:id='NISTp10_-12'>
461
+ <PrefixName xml:lang='en'>pico</PrefixName>
462
+ <PrefixSymbol type='ASCII'>p</PrefixSymbol>
463
+ <PrefixSymbol type='unicode'>p</PrefixSymbol>
464
+ <PrefixSymbol type='LaTeX'>p</PrefixSymbol>
465
+ <PrefixSymbol type='HTML'>p</PrefixSymbol>
466
+ </Prefix>
467
+ <mrow xref='NISTp10_1'>
468
+ <mi mathvariant='normal'>da</mi>
469
+ </mrow>
470
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='1' xml:id='NISTp10_1'>
471
+ <PrefixName xml:lang='en'>deka</PrefixName>
472
+ <PrefixSymbol type='ASCII'>da</PrefixSymbol>
473
+ <PrefixSymbol type='unicode'>da</PrefixSymbol>
474
+ <PrefixSymbol type='LaTeX'>da</PrefixSymbol>
475
+ <PrefixSymbol type='HTML'>da</PrefixSymbol>
476
+ </Prefix>
477
+ </math>
478
+ OUTPUT
479
+ end
480
+
481
+ it "deals with units division" do
482
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
483
+ 9 "unitsml(A*C^3)" + 13 "unitsml(A/C^-3)"
484
+ INPUT
485
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
180
486
  <mn>9</mn>
181
487
  <mo rspace='thickmathspace'>&#x2062;</mo>
182
- <mrow xref='U_C3.A'>
488
+ <mrow xref='U_A.C3'>
489
+ <mi mathvariant='normal'>A</mi>
490
+ <mo>&#xB7;</mo>
183
491
  <msup>
184
492
  <mrow>
185
493
  <mi mathvariant='normal'>C</mi>
@@ -188,20 +496,19 @@ RSpec.describe Asciimath2UnitsML do
188
496
  <mn>3</mn>
189
497
  </mrow>
190
498
  </msup>
191
- <mo>&#xB7;</mo>
192
- <mi mathvariant='normal'>A</mi>
193
499
  </mrow>
194
- <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_C3.A' dimensionURL='#D_T3I4'>
500
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_A.C3' dimensionURL='#D_M3I4'>
195
501
  <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
196
- <UnitName xml:lang='en'>C^3*A</UnitName>
502
+ <UnitName xml:lang='en'>A*C^3</UnitName>
197
503
  <UnitSymbol type='HTML'>
198
- C
504
+ A&#xB7;C
199
505
  <sup>3</sup>
200
- &#xB7;A
201
506
  </UnitSymbol>
202
507
  <UnitSymbol type='MathML'>
203
508
  <math xmlns='http://www.w3.org/1998/Math/MathML'>
204
509
  <mrow>
510
+ <mi mathvariant='normal'>A</mi>
511
+ <mo>&#xB7;</mo>
205
512
  <msup>
206
513
  <mrow>
207
514
  <mi mathvariant='normal'>C</mi>
@@ -210,40 +517,108 @@ RSpec.describe Asciimath2UnitsML do
210
517
  <mn>3</mn>
211
518
  </mrow>
212
519
  </msup>
213
- <mo>&#xB7;</mo>
214
- <mi mathvariant='normal'>A</mi>
215
520
  </mrow>
216
521
  </math>
217
522
  </UnitSymbol>
218
523
  <RootUnits>
219
- <EnumeratedRootUnit unit='coulomb' powerNumerator='3'/>
220
524
  <EnumeratedRootUnit unit='ampere'/>
525
+ <EnumeratedRootUnit unit='coulomb' powerNumerator='3'/>
221
526
  </RootUnits>
222
527
  </Unit>
223
- <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_T3I4'>
224
- <Time symbol='T' powerNumerator='3'/>
528
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_M3I4'>
529
+ <Mass symbol='M' powerNumerator='3'/>
225
530
  <ElectricCurrent symbol='I' powerNumerator='4'/>
226
531
  </Dimension>
227
532
  <mo>+</mo>
228
- <mn>7</mn>
533
+ <mn>13</mn>
229
534
  <mo rspace='thickmathspace'>&#x2062;</mo>
230
- <mrow xref='U_NISTu284'>
231
- <mi mathvariant='normal'>hp</mi>
535
+ <mrow xref='U_A/C-3'>
536
+ <mi mathvariant='normal'>A</mi>
537
+ <mo>/</mo>
538
+ <msup>
539
+ <mrow>
540
+ <mi mathvariant='normal'>C</mi>
541
+ </mrow>
542
+ <mrow>
543
+ <mo>&#x2212;</mo>
544
+ <mn>3</mn>
545
+ </mrow>
546
+ </msup>
232
547
  </mrow>
233
- <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu284'>
234
- <UnitSystem name='not_SI' type='not_SI' xml:lang='en-US'/>
235
- <UnitName xml:lang='en'>horsepower</UnitName>
236
- <UnitSymbol type='HTML'>hp</UnitSymbol>
237
- <UnitSymbol type='MathML'>
238
- <math xmlns='http://www.w3.org/1998/Math/MathML'>
239
- <mrow>
240
- <mi mathvariant='normal'>hp</mi>
241
- </mrow>
242
- </math>
243
- </UnitSymbol>
244
- </Unit>
245
548
  </math>
246
- OUTPUT
549
+ OUTPUT
550
+ end
551
+
552
+ it "converts MathML to MatML + UnitsML" do
553
+ input = <<~INPUT
554
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
555
+ <mn>32</mn>
556
+ <mo>+</mo>
557
+ <mn>5</mn>
558
+ <mo>&#xD7;</mo>
559
+ <mn>7</mn>
560
+ <mtext>unitsml(kg^-2)</mtext>
561
+ </math>
562
+ INPUT
563
+ output = <<~OUTPUT
564
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
565
+ <mn>32</mn>
566
+ <mo>+</mo>
567
+ <mn>5</mn>
568
+ <mo>&#xD7;</mo>
569
+ <mn>7</mn>
570
+ <mo rspace='thickmathspace'>&#x2062;</mo>
571
+ <mrow xref='U_kg-2'>
572
+ <msup>
573
+ <mrow>
574
+ <mi mathvariant='normal'>kg</mi>
575
+ </mrow>
576
+ <mrow>
577
+ <mo>&#x2212;</mo>
578
+ <mn>2</mn>
579
+ </mrow>
580
+ </msup>
581
+ </mrow>
582
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg-2' dimensionURL='#D_M-2'>
583
+ <UnitSystem name='SI' type='SI_base' xml:lang='en-US'/>
584
+ <UnitName xml:lang='en'>kg^-2</UnitName>
585
+ <UnitSymbol type='HTML'>
586
+ kg
587
+ <sup>&#x2212;2</sup>
588
+ </UnitSymbol>
589
+ <UnitSymbol type='MathML'>
590
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
591
+ <mrow>
592
+ <msup>
593
+ <mrow>
594
+ <mi mathvariant='normal'>kg</mi>
595
+ </mrow>
596
+ <mrow>
597
+ <mo>&#x2212;</mo>
598
+ <mn>2</mn>
599
+ </mrow>
600
+ </msup>
601
+ </mrow>
602
+ </math>
603
+ </UnitSymbol>
604
+ <RootUnits>
605
+ <EnumeratedRootUnit unit='gram' prefix='k' powerNumerator='-2'/>
606
+ </RootUnits>
607
+ </Unit>
608
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='3' xml:id='NISTp10_3'>
609
+ <PrefixName xml:lang='en'>kilo</PrefixName>
610
+ <PrefixSymbol type='ASCII'>k</PrefixSymbol>
611
+ <PrefixSymbol type='unicode'>k</PrefixSymbol>
612
+ <PrefixSymbol type='LaTeX'>k</PrefixSymbol>
613
+ <PrefixSymbol type='HTML'>k</PrefixSymbol>
614
+ </Prefix>
615
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_M-2'>
616
+ <Mass symbol='M' powerNumerator='-2'/>
617
+ </Dimension>
618
+ </math>
619
+ OUTPUT
620
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().MathML2UnitsML(input).to_xml)).to be_equivalent_to xmlpp(output)
621
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().MathML2UnitsML(Nokogiri::XML(input)).to_xml)).to be_equivalent_to xmlpp(output)
247
622
  end
248
623
 
249
624
  it "raises error for illegal unit" do
@@ -272,7 +647,7 @@ RSpec.describe Asciimath2UnitsML do
272
647
  </mrow>
273
648
  </msup>
274
649
  </mrow>
275
- <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg.s-2' dimensionURL='#D_MT-2'>
650
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg.s-2' dimensionURL='#NISTd37'>
276
651
  <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
277
652
  <UnitName xml:lang='en'>kg*s^-2</UnitName>
278
653
  <UnitSymbol type='HTML'>
@@ -304,8 +679,11 @@ RSpec.describe Asciimath2UnitsML do
304
679
  <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='3' xml:id='NISTp10_3'>
305
680
  <PrefixName xml:lang='en'>kilo</PrefixName>
306
681
  <PrefixSymbol type='ASCII'>k</PrefixSymbol>
682
+ <PrefixSymbol type='unicode'>k</PrefixSymbol>
683
+ <PrefixSymbol type='LaTeX'>k</PrefixSymbol>
684
+ <PrefixSymbol type='HTML'>k</PrefixSymbol>
307
685
  </Prefix>
308
- <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_MT-2'>
686
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd37'>
309
687
  <Mass symbol='M' powerNumerator='1'/>
310
688
  <Time symbol='T' powerNumerator='-2'/>
311
689
  </Dimension>
@@ -315,59 +693,62 @@ RSpec.describe Asciimath2UnitsML do
315
693
  1 "unitsml(kg*s^-2)"
316
694
  INPUT
317
695
  <math xmlns='http://www.w3.org/1998/Math/MathML'>
318
- <mn>1</mn>
319
- <mo rspace='thickmathspace'>&#x2062;</mo>
320
- <mrow xref='U_kg.s-2'>
321
- <mi mathvariant='normal'>kg</mi>
322
- <mo rspace='thickmathspace'>&#x2062;</mo>
323
- <msup>
324
- <mrow>
325
- <mi mathvariant='normal'>s</mi>
326
- </mrow>
327
- <mrow>
328
- <mo>&#x2212;</mo>
329
- <mn>2</mn>
330
- </mrow>
331
- </msup>
332
- </mrow>
333
- <unit xmlns='http://unitsml.nist.gov/2005' dimensionurl='#D_MT-2' xml:id='U_kg.s-2'>
334
- <unitsystem name='SI' type='SI_derived' xml:lang='en-US'/>
335
- <unitname xml:lang='en'>kg*s^-2</unitname>
336
- <unitsymbol type='HTML'>
337
- kg&#xA0;s
338
- <sup>&#x2212;2</sup>
339
- </unitsymbol>
340
- <unitsymbol type='MathML'>
341
- <math xmlns='http://www.w3.org/1998/Math/MathML'>
342
- <mrow>
343
- <mi mathvariant='normal'>kg</mi>
344
- <mo rspace='thickmathspace'>&#x2062;</mo>
345
- <msup>
346
- <mrow>
347
- <mi mathvariant='normal'>s</mi>
348
- </mrow>
349
- <mrow>
350
- <mo>&#x2212;</mo>
351
- <mn>2</mn>
352
- </mrow>
353
- </msup>
354
- </mrow>
355
- </math>
356
- </unitsymbol>
357
- <rootunits>
358
- <enumeratedrootunit unit='gram' prefix='k'/>
359
- <enumeratedrootunit unit='second' powernumerator='-2'/>
360
- </rootunits>
361
- </unit>
362
- <prefix xmlns='http://unitsml.nist.gov/2005' prefixbase='10' prefixpower='3' xml:id='NISTp10_3'>
363
- <prefixname xml:lang='en'>kilo</prefixname>
364
- <prefixsymbol type='ASCII'>k</prefixsymbol>
365
- </prefix>
366
- <dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_MT-2'>
367
- <mass symbol='M' powernumerator='1'/>
368
- <time symbol='T' powernumerator='-2'/>
369
- </dimension>
370
- </math>
696
+ <mn>1</mn>
697
+ <mo rspace='thickmathspace'>&#x2062;</mo>
698
+ <mrow xref='U_kg.s-2'>
699
+ <mi mathvariant='normal'>kg</mi>
700
+ <mo rspace='thickmathspace'>&#x2062;</mo>
701
+ <msup>
702
+ <mrow>
703
+ <mi mathvariant='normal'>s</mi>
704
+ </mrow>
705
+ <mrow>
706
+ <mo>&#x2212;</mo>
707
+ <mn>2</mn>
708
+ </mrow>
709
+ </msup>
710
+ </mrow>
711
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg.s-2' dimensionURL='#NISTd37'>
712
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
713
+ <UnitName xml:lang='en'>kg*s^-2</UnitName>
714
+ <UnitSymbol type='HTML'>
715
+ kg&#xA0;s
716
+ <sup>&#x2212;2</sup>
717
+ </UnitSymbol>
718
+ <UnitSymbol type='MathML'>
719
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
720
+ <mrow>
721
+ <mi mathvariant='normal'>kg</mi>
722
+ <mo rspace='thickmathspace'>&#x2062;</mo>
723
+ <msup>
724
+ <mrow>
725
+ <mi mathvariant='normal'>s</mi>
726
+ </mrow>
727
+ <mrow>
728
+ <mo>&#x2212;</mo>
729
+ <mn>2</mn>
730
+ </mrow>
731
+ </msup>
732
+ </mrow>
733
+ </math>
734
+ </UnitSymbol>
735
+ <RootUnits>
736
+ <EnumeratedRootUnit unit='gram' prefix='k'/>
737
+ <EnumeratedRootUnit unit='second' powerNumerator='-2'/>
738
+ </RootUnits>
739
+ </Unit>
740
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='3' xml:id='NISTp10_3'>
741
+ <PrefixName xml:lang='en'>kilo</PrefixName>
742
+ <PrefixSymbol type='ASCII'>k</PrefixSymbol>
743
+ <PrefixSymbol type='unicode'>k</PrefixSymbol>
744
+ <PrefixSymbol type='LaTeX'>k</PrefixSymbol>
745
+ <PrefixSymbol type='HTML'>k</PrefixSymbol>
746
+ </Prefix>
747
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd37'>
748
+ <Mass symbol='M' powerNumerator='1'/>
749
+ <Time symbol='T' powerNumerator='-2'/>
750
+ </Dimension>
751
+ </math>
371
752
  OUTPUT
372
753
  expect(xmlpp(Asciimath2UnitsML::Conv.new(multiplier: :nospace).Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
373
754
  1 "unitsml(kg*s^-2)"
@@ -388,7 +769,7 @@ RSpec.describe Asciimath2UnitsML do
388
769
  </mrow>
389
770
  </msup>
390
771
  </mrow>
391
- <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg.s-2' dimensionURL='#D_MT-2'>
772
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_kg.s-2' dimensionURL='#NISTd37'>
392
773
  <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
393
774
  <UnitName xml:lang='en'>kg*s^-2</UnitName>
394
775
  <UnitSymbol type='HTML'>
@@ -420,12 +801,283 @@ RSpec.describe Asciimath2UnitsML do
420
801
  <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='3' xml:id='NISTp10_3'>
421
802
  <PrefixName xml:lang='en'>kilo</PrefixName>
422
803
  <PrefixSymbol type='ASCII'>k</PrefixSymbol>
804
+ <PrefixSymbol type='unicode'>k</PrefixSymbol>
805
+ <PrefixSymbol type='LaTeX'>k</PrefixSymbol>
806
+ <PrefixSymbol type='HTML'>k</PrefixSymbol>
423
807
  </Prefix>
424
- <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='D_MT-2'>
808
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd37'>
425
809
  <Mass symbol='M' powerNumerator='1'/>
426
810
  <Time symbol='T' powerNumerator='-2'/>
427
811
  </Dimension>
428
812
  </math>
429
813
  OUTPUT
430
814
  end
815
+
816
+ it "deals with dimension decomposition with like units" do
817
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
818
+ 9 "unitsml(mW*cm^(-2))"
819
+ INPUT
820
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
821
+ <mn>9</mn>
822
+ <mo rspace='thickmathspace'>&#x2062;</mo>
823
+ <mrow xref='U_mW.cm-2'>
824
+ <mi mathvariant='normal'>mW</mi>
825
+ <mo>&#xB7;</mo>
826
+ <msup>
827
+ <mrow>
828
+ <mi mathvariant='normal'>cm</mi>
829
+ </mrow>
830
+ <mrow>
831
+ <mo>&#x2212;</mo>
832
+ <mn>2</mn>
833
+ </mrow>
834
+ </msup>
835
+ </mrow>
836
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_mW.cm-2'>
837
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
838
+ <UnitName xml:lang='en'>mW*cm^-2</UnitName>
839
+ <UnitSymbol type='HTML'>
840
+ mW&#xB7;cm
841
+ <sup>&#x2212;2</sup>
842
+ </UnitSymbol>
843
+ <UnitSymbol type='MathML'>
844
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
845
+ <mrow>
846
+ <mi mathvariant='normal'>mW</mi>
847
+ <mo>&#xB7;</mo>
848
+ <msup>
849
+ <mrow>
850
+ <mi mathvariant='normal'>cm</mi>
851
+ </mrow>
852
+ <mrow>
853
+ <mo>&#x2212;</mo>
854
+ <mn>2</mn>
855
+ </mrow>
856
+ </msup>
857
+ </mrow>
858
+ </math>
859
+ </UnitSymbol>
860
+ <RootUnits>
861
+ <EnumeratedRootUnit unit='watt' prefix='m'/>
862
+ <EnumeratedRootUnit unit='meter' prefix='c' powerNumerator='-2'/>
863
+ </RootUnits>
864
+ </Unit>
865
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='-3' xml:id='NISTp10_-3'>
866
+ <PrefixName xml:lang='en'>milli</PrefixName>
867
+ <PrefixSymbol type='ASCII'>m</PrefixSymbol>
868
+ <PrefixSymbol type='unicode'>m</PrefixSymbol>
869
+ <PrefixSymbol type='LaTeX'>m</PrefixSymbol>
870
+ <PrefixSymbol type='HTML'>m</PrefixSymbol>
871
+ </Prefix>
872
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='-2' xml:id='NISTp10_-2'>
873
+ <PrefixName xml:lang='en'>centi</PrefixName>
874
+ <PrefixSymbol type='ASCII'>c</PrefixSymbol>
875
+ <PrefixSymbol type='unicode'>c</PrefixSymbol>
876
+ <PrefixSymbol type='LaTeX'>c</PrefixSymbol>
877
+ <PrefixSymbol type='HTML'>c</PrefixSymbol>
878
+ </Prefix>
879
+ </math>
880
+ OUTPUT
881
+ end
882
+
883
+ it "deals with quantity input" do
884
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
885
+ 9 "unitsml(m, quantity: NISTq103)"
886
+ INPUT
887
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
888
+ <mn>9</mn>
889
+ <mo rspace='thickmathspace'>&#x2062;</mo>
890
+ <mrow xref='U_NISTu1'>
891
+ <mi mathvariant='normal'>m</mi>
892
+ </mrow>
893
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu1' dimensionURL='#NISTd1'>
894
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
895
+ <UnitName xml:lang='en'>meter</UnitName>
896
+ <UnitSymbol type='HTML'>m</UnitSymbol>
897
+ <UnitSymbol type='MathML'>
898
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
899
+ <mrow>
900
+ <mi mathvariant='normal'>m</mi>
901
+ </mrow>
902
+ </math>
903
+ </UnitSymbol>
904
+ </Unit>
905
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd1'>
906
+ <Length symbol='L' powerNumerator='1'/>
907
+ </Dimension>
908
+ <Quantity xmlns='http://unitsml.nist.gov/2005' xml:id='NISTq103' dimensionURL='#NISTd1' quantityType='base'>
909
+ <QuantityName xml:lang='en-US'>position vector</QuantityName>
910
+ </Quantity>
911
+ </math>
912
+ OUTPUT
913
+ end
914
+
915
+ it "deals with name input" do
916
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
917
+ 9 "unitsml(cal_th/cm^2, name: langley)"
918
+ INPUT
919
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
920
+ <mn>9</mn>
921
+ <mo rspace='thickmathspace'>&#x2062;</mo>
922
+ <mrow xref='U_cal_th/cm2'>
923
+ <msub>
924
+ <mrow>
925
+ <mi mathvariant='normal'>cal</mi>
926
+ </mrow>
927
+ <mrow>
928
+ <mi mathvariant='normal'>th</mi>
929
+ </mrow>
930
+ </msub>
931
+ <mo>/</mo>
932
+ <msup>
933
+ <mrow>
934
+ <mi mathvariant='normal'>cm</mi>
935
+ </mrow>
936
+ <mrow>
937
+ <mn>2</mn>
938
+ </mrow>
939
+ </msup>
940
+ </mrow>
941
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_cal_th.cm-2'>
942
+ <UnitSystem name='not_SI' type='not_SI' xml:lang='en-US'/>
943
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
944
+ <UnitName xml:lang='en'>langley</UnitName>
945
+ <UnitSymbol type='HTML'>
946
+ cal
947
+ <sub>th</sub>
948
+ &#xB7;cm
949
+ <sup>&#x2212;2</sup>
950
+ </UnitSymbol>
951
+ <UnitSymbol type='MathML'>
952
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
953
+ <mrow>
954
+ <msub>
955
+ <mrow>
956
+ <mi mathvariant='normal'>cal</mi>
957
+ </mrow>
958
+ <mrow>
959
+ <mi mathvariant='normal'>th</mi>
960
+ </mrow>
961
+ </msub>
962
+ <mo>&#xB7;</mo>
963
+ <msup>
964
+ <mrow>
965
+ <mi mathvariant='normal'>cm</mi>
966
+ </mrow>
967
+ <mrow>
968
+ <mo>&#x2212;</mo>
969
+ <mn>2</mn>
970
+ </mrow>
971
+ </msup>
972
+ </mrow>
973
+ </math>
974
+ </UnitSymbol>
975
+ <RootUnits>
976
+ <EnumeratedRootUnit unit='thermochemical calorie'/>
977
+ <EnumeratedRootUnit unit='meter' prefix='c' powerNumerator='-2'/>
978
+ </RootUnits>
979
+ </Unit>
980
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='-2' xml:id='NISTp10_-2'>
981
+ <PrefixName xml:lang='en'>centi</PrefixName>
982
+ <PrefixSymbol type='ASCII'>c</PrefixSymbol>
983
+ <PrefixSymbol type='unicode'>c</PrefixSymbol>
984
+ <PrefixSymbol type='LaTeX'>c</PrefixSymbol>
985
+ <PrefixSymbol type='HTML'>c</PrefixSymbol>
986
+ </Prefix>
987
+ </math>
988
+ OUTPUT
989
+ end
990
+
991
+ it "deals with symbol input" do
992
+ expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
993
+ 9 "unitsml(m, symbol: La)" + 10 "unitsml(cm*s^-2, symbol: cm cdot s^-2)"
994
+ INPUT
995
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
996
+ <mn>9</mn>
997
+ <mo rspace='thickmathspace'>&#x2062;</mo>
998
+ <mrow xref='U_NISTu1'>
999
+ <math>
1000
+ <mi mathvariant='normal'>L</mi>
1001
+ <mi mathvariant='normal'>a</mi>
1002
+ </math>
1003
+ </mrow>
1004
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_NISTu1' dimensionURL='#NISTd1'>
1005
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
1006
+ <UnitName xml:lang='en'>meter</UnitName>
1007
+ <UnitSymbol type='HTML'>m</UnitSymbol>
1008
+ <UnitSymbol type='MathML'>
1009
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
1010
+ <mrow>
1011
+ <mi mathvariant='normal'>m</mi>
1012
+ </mrow>
1013
+ </math>
1014
+ </UnitSymbol>
1015
+ </Unit>
1016
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd1'>
1017
+ <Length symbol='L' powerNumerator='1'/>
1018
+ </Dimension>
1019
+ <mo>+</mo>
1020
+ <mn>10</mn>
1021
+ <mo rspace='thickmathspace'>&#x2062;</mo>
1022
+ <mrow xref='U_cm.s-2'>
1023
+ <math>
1024
+ <mi mathvariant='normal'>c</mi>
1025
+ <mi mathvariant='normal'>m</mi>
1026
+ <mo>&#x22C5;</mo>
1027
+ <msup>
1028
+ <mrow>
1029
+ <mi mathvariant='normal'>s</mi>
1030
+ </mrow>
1031
+ <mrow>
1032
+ <mo>&#x2212;</mo>
1033
+ </mrow>
1034
+ </msup>
1035
+ <mn>2</mn>
1036
+ </math>
1037
+ </mrow>
1038
+ <Unit xmlns='http://unitsml.nist.gov/2005' xml:id='U_cm.s-2' dimensionURL='#NISTd28'>
1039
+ <UnitSystem name='SI' type='SI_derived' xml:lang='en-US'/>
1040
+ <UnitName xml:lang='en'>cm*s^-2</UnitName>
1041
+ <UnitSymbol type='HTML'>
1042
+ cm&#xB7;s
1043
+ <sup>&#x2212;2</sup>
1044
+ </UnitSymbol>
1045
+ <UnitSymbol type='MathML'>
1046
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
1047
+ <mrow>
1048
+ <mi mathvariant='normal'>cm</mi>
1049
+ <mo>&#xB7;</mo>
1050
+ <msup>
1051
+ <mrow>
1052
+ <mi mathvariant='normal'>s</mi>
1053
+ </mrow>
1054
+ <mrow>
1055
+ <mo>&#x2212;</mo>
1056
+ <mn>2</mn>
1057
+ </mrow>
1058
+ </msup>
1059
+ </mrow>
1060
+ </math>
1061
+ </UnitSymbol>
1062
+ <RootUnits>
1063
+ <EnumeratedRootUnit unit='meter' prefix='c'/>
1064
+ <EnumeratedRootUnit unit='second' powerNumerator='-2'/>
1065
+ </RootUnits>
1066
+ </Unit>
1067
+ <Prefix xmlns='http://unitsml.nist.gov/2005' prefixBase='10' prefixPower='-2' xml:id='NISTp10_-2'>
1068
+ <PrefixName xml:lang='en'>centi</PrefixName>
1069
+ <PrefixSymbol type='ASCII'>c</PrefixSymbol>
1070
+ <PrefixSymbol type='unicode'>c</PrefixSymbol>
1071
+ <PrefixSymbol type='LaTeX'>c</PrefixSymbol>
1072
+ <PrefixSymbol type='HTML'>c</PrefixSymbol>
1073
+ </Prefix>
1074
+ <Dimension xmlns='http://unitsml.nist.gov/2005' xml:id='NISTd28'>
1075
+ <Length symbol='L' powerNumerator='1'/>
1076
+ <Time symbol='T' powerNumerator='-2'/>
1077
+ </Dimension>
1078
+ </math>
1079
+ OUTPUT
1080
+ end
1081
+
1082
+
431
1083
  end