asciimath2unitsml 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +16 -0
- data/lib/asciimath2unitsml/conv.rb +14 -7
- data/lib/asciimath2unitsml/parse.rb +26 -7
- data/lib/asciimath2unitsml/render.rb +38 -14
- data/lib/asciimath2unitsml/unit.rb +5 -2
- data/lib/asciimath2unitsml/version.rb +1 -1
- data/lib/unitsdb/quantities.yaml +21 -0
- data/lib/unitsdb/units.yaml +70 -0
- data/spec/conv_spec.rb +276 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 939880ec148bae10c193dc7958d2866ff5788d7e98617158bfde25a736576b13
|
4
|
+
data.tar.gz: dc8d0afdfc6c134341735b55bfed5ae68b50da906ea5765e8404135d58adf011
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2f5e07977df15d3354ce4e509c585de929caf592ccd9ccd6974d5830b932b0982bd1c7c3cc0483c028e64846032925907316406f0f95cb9c6dda49ecb1ef2b6
|
7
|
+
data.tar.gz: e1f358839665b8b815772e32c30ecaea7581061962d7b87cb5e844aaddaed666ae1b95fb2885e7f8eff4bc0d656325660eeba5cf5a45414690614e987da7f31f
|
data/README.adoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
image:https://img.shields.io/gem/v/asciimath2unitsml.svg["Gem Version", link="https://rubygems.org/gems/asciimath2unitsml"]
|
2
|
+
image:https://github.com/plurimath/asciimath2unitsml/workflows/rake/badge.svg["Build Status", link="https://github.com/plurimath/asciimath2unitsml/actions?workflow=rake"]
|
3
|
+
// image:https://codeclimate.com/github/plurimath/asciimath2unitsml/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/plurimath/asciimath2unitsml"]
|
4
|
+
image:https://img.shields.io/github/issues-pr-raw/plurimath/asciimath2unitsml.svg["Pull Requests", link="https://github.com/plurimath/asciimath2unitsml/pulls"]
|
5
|
+
image:https://img.shields.io/github/commits-since/plurimath/asciimath2unitsml/latest.svg["Commits since latest",link="https://github.com/plurimath/asciimath2unitsml/releases"]
|
6
|
+
|
1
7
|
= asciimath2unitsml
|
2
8
|
Convert Units expressions via MathML to UnitsML
|
3
9
|
|
@@ -43,6 +49,13 @@ https://github.com/unitsml/unitsdb/blob/master/units.yaml[]), that quantity is a
|
|
43
49
|
otherwise, no quantity is added unless explicitly nominated in this way.
|
44
50
|
* `unitsml(unit-string, name: NAME)` provides a name for the unit, if one is not already available
|
45
51
|
from UnitsDB. For example, `unitsml(cal_th/cm^2, name: langley)`.
|
52
|
+
* `unitsml(unit-string, symbol: SYMBOL)` provides an alternate symbol for the unit, in AsciiMath.
|
53
|
+
The unit-string gives the canonical representation of the unit, but SYMBOL is what will be rendered.
|
54
|
+
For example, `unitsml(cal_th/cm^2, name: langley, symbol: La)`, or `unitsml(mm*s^-2, symbol: mm cdot s^-2)`.
|
55
|
+
(All variables in SYMBOL are rendered upright, as is the default for units.)
|
56
|
+
|
57
|
+
Standalone prefixes can be recognised by replacing the unit with hyphen; so `unitsml(p-)` corresponds
|
58
|
+
to the standalone prefix "pico" (and is rendered as "p").
|
46
59
|
|
47
60
|
== Rendering
|
48
61
|
|
@@ -54,6 +67,9 @@ The gem follows the MathML Units convention of inserting a spacing invisible tim
|
|
54
67
|
(`<mo rspace='thickmathspace'>⁢</mo>`) between any numbers (`<mn>`) and unit expressions
|
55
68
|
in MathML, and representing units in MathML as non-italic variables (`<mi mathvariant='normal'>`).
|
56
69
|
|
70
|
+
Space is not inserted between a number and a unit expression, when that unit expression wholly consists
|
71
|
+
of punctuation: _1 m_, _1 °C_, but _9° 7′ 22″_.
|
72
|
+
|
57
73
|
== Example
|
58
74
|
|
59
75
|
[source]
|
@@ -35,6 +35,10 @@ module Asciimath2UnitsML
|
|
35
35
|
@multiplier = multiplier(options[:multiplier] || "\u00b7")
|
36
36
|
end
|
37
37
|
|
38
|
+
def float_to_display(f)
|
39
|
+
ret = f.to_f.round(1).to_s.sub(/\.0$/, "")
|
40
|
+
end
|
41
|
+
|
38
42
|
def prefix(units)
|
39
43
|
units.map { |u| u[:prefix] }.reject { |u| u.nil? }.uniq.map do |p|
|
40
44
|
<<~END
|
@@ -61,7 +65,7 @@ module Asciimath2UnitsML
|
|
61
65
|
|
62
66
|
def units2dimensions(units)
|
63
67
|
norm = decompose_units(units)
|
64
|
-
return if norm.any? { |u| u[:unit] == "unknown" || u[:prefix] == "unknown" }
|
68
|
+
return if norm.any? { |u| u[:unit] == "unknown" || u[:prefix] == "unknown" || u[:unit].nil? }
|
65
69
|
norm.map do |u|
|
66
70
|
{ dimension: U2D[u[:unit]][:dimension],
|
67
71
|
unit: u[:unit],
|
@@ -71,7 +75,7 @@ module Asciimath2UnitsML
|
|
71
75
|
end
|
72
76
|
|
73
77
|
def dimension1(u)
|
74
|
-
%(<#{u[:dimension]} symbol="#{u[:symbol]}" powerNumerator="#{u[:exponent]}"/>)
|
78
|
+
%(<#{u[:dimension]} symbol="#{u[:symbol]}" powerNumerator="#{float_to_display(u[:exponent])}"/>)
|
75
79
|
end
|
76
80
|
|
77
81
|
def dim_id(dims)
|
@@ -81,7 +85,9 @@ module Asciimath2UnitsML
|
|
81
85
|
AmountOfSubstance LuminousIntensity PlaneAngle)
|
82
86
|
.map { |h| dimhash.dig(h, :exponent) }.join(":")
|
83
87
|
id = @dimensions_id&.values&.select { |d| d.vector == dimsvector }&.first&.id and return id.to_s
|
84
|
-
"D_" + dims.map
|
88
|
+
"D_" + dims.map do |d|
|
89
|
+
U2D[d[:unit]][:symbol] + (d[:exponent] == 1 ? "" : float_to_display(d[:exponent]))
|
90
|
+
end.join("")
|
85
91
|
end
|
86
92
|
|
87
93
|
def decompose_units(units)
|
@@ -94,7 +100,7 @@ module Asciimath2UnitsML
|
|
94
100
|
else
|
95
101
|
m[-1] = { prefix: combine_prefixes(@prefixes[m[-1][:prefix]], @prefixes[k[:prefix]]),
|
96
102
|
unit: m[-1][:unit],
|
97
|
-
exponent: (k[:exponent]&.
|
103
|
+
exponent: (k[:exponent]&.to_f || 1) + (m[-1][:exponent]&.to_f || 1) }
|
98
104
|
end
|
99
105
|
end
|
100
106
|
end
|
@@ -102,7 +108,8 @@ module Asciimath2UnitsML
|
|
102
108
|
# treat g not kg as base unit: we have stripped the prefix k in parsing
|
103
109
|
# reduce units down to basic units
|
104
110
|
def decompose_unit(u)
|
105
|
-
if u[:unit]
|
111
|
+
if u[:unit].nil? then u
|
112
|
+
elsif u[:unit] == "g" then u
|
106
113
|
elsif @units[u[:unit]].system_type == "SI_base" then u
|
107
114
|
elsif !@units[u[:unit]].si_derived_bases
|
108
115
|
{ prefix: u[:prefix], unit: "unknown", exponent: u[:exponent] }
|
@@ -111,7 +118,7 @@ module Asciimath2UnitsML
|
|
111
118
|
m << { prefix: !k[:prefix].nil? && !k[:prefix].empty? ?
|
112
119
|
combine_prefixes(@prefixes_id[k[:prefix]], @prefixes[u[:prefix]]) : u[:prefix],
|
113
120
|
unit: @units_id[k[:id]].symbolid,
|
114
|
-
exponent: (k[:power]&.to_i || 1) * (u[:exponent]&.
|
121
|
+
exponent: (k[:power]&.to_i || 1) * (u[:exponent]&.to_f || 1) }
|
115
122
|
end
|
116
123
|
end
|
117
124
|
end
|
@@ -121,7 +128,7 @@ module Asciimath2UnitsML
|
|
121
128
|
return p1.symbolid if p2.nil?
|
122
129
|
return p2.symbolid if p1.nil?
|
123
130
|
return "unknown" if p1.base != p2.base
|
124
|
-
@prefixes.each do |p|
|
131
|
+
@prefixes.each do |_, p|
|
125
132
|
return p.symbolid if p.base == p1.base && p.power == p1.power + p2.power
|
126
133
|
end
|
127
134
|
"unknown"
|
@@ -94,12 +94,17 @@ module Asciimath2UnitsML
|
|
94
94
|
/\^-?\d+/.r.map { |m| m.sub(/\^/, "") }
|
95
95
|
multiplier = %r{\*|//|/}.r.map { |x| { multiplier: x[0] } }
|
96
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" } } |
|
97
100
|
seq(unit1, exponent._? & multiplier) { |x| { prefix: nil, unit: x[0], display_exponent: (x[1][0] )} } |
|
98
101
|
seq(unit1, exponent._?).eof { |x| { prefix: nil, unit: x[0], display_exponent: (x[1][0] )} } |
|
99
102
|
seq(prefix1, unit1, exponent._? ) { |x| { prefix: x[0], unit: x[1], display_exponent: (x[2][0] ) } } |
|
100
103
|
seq(prefix2, unit1, exponent._? ) { |x| { prefix: x[0], unit: x[1], display_exponent: (x[2][0] ) } } |
|
101
|
-
"1".r.map { |_| { prefix: nil, unit: "1", display_exponent: nil } }
|
102
|
-
units =
|
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)
|
103
108
|
parser = units.eof
|
104
109
|
end
|
105
110
|
|
@@ -117,11 +122,12 @@ module Asciimath2UnitsML
|
|
117
122
|
units = postprocess1(units)
|
118
123
|
quantity = text[1..-1]&.select { |x| /^quantity:/.match(x) }&.first&.sub(/^quantity:\s*/, "")
|
119
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*/, "")
|
120
126
|
normtext = units_only(units).each.map do |u|
|
121
127
|
exp = u[:exponent] && u[:exponent] != "1" ? "^#{u[:exponent]}" : ""
|
122
128
|
"#{u[:prefix]}#{u[:unit]}#{exp}"
|
123
129
|
end.join("*")
|
124
|
-
[units, text[0], normtext, quantity, name]
|
130
|
+
[units, text[0], normtext, quantity, name, symbol]
|
125
131
|
end
|
126
132
|
|
127
133
|
def postprocess1(units)
|
@@ -148,7 +154,7 @@ module Asciimath2UnitsML
|
|
148
154
|
"mol" => { dimension: "AmountOfSubstance", order: 6, symbol: "N" },
|
149
155
|
"cd" => { dimension: "LuminousIntensity", order: 7, symbol: "J" },
|
150
156
|
"deg" => { dimension: "PlaneAngle", order: 8, symbol: "Phi" },
|
151
|
-
}
|
157
|
+
}.freeze
|
152
158
|
|
153
159
|
def Asciimath2UnitsML(expression)
|
154
160
|
xml = Nokogiri::XML(asciimath2mathml(expression))
|
@@ -161,14 +167,21 @@ module Asciimath2UnitsML
|
|
161
167
|
xml.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
|
162
168
|
next unless %r{^unitsml\(.+\)$}.match(x.text)
|
163
169
|
text = x.text.sub(%r{^unitsml\((.+)\)$}m, "\\1")
|
164
|
-
units, origtext, normtext, quantity, name = parse(text)
|
165
|
-
|
166
|
-
x
|
170
|
+
units, origtext, normtext, quantity, name, symbol = parse(text)
|
171
|
+
rendering = symbol ? embeddedmathml(asciimath2mathml(symbol)) : mathmlsymbol(units, false)
|
172
|
+
delim = x&.previous_element&.name == "mn" ? delimspace(rendering) : ""
|
173
|
+
x.replace("#{delim}<mrow xref='#{unit_id(origtext)}'>#{rendering}</mrow>\n"\
|
167
174
|
"#{unitsml(units, origtext, normtext, quantity, name)}")
|
168
175
|
end
|
169
176
|
dedup_ids(xml)
|
170
177
|
end
|
171
178
|
|
179
|
+
def delimspace(x)
|
180
|
+
text = HTMLEntities.new.encode(Nokogiri::XML("<mrow>#{x}</mrow>").text.strip)
|
181
|
+
/[[:alnum:]]/.match(text) ?
|
182
|
+
"<mo rspace='thickmathspace'>⁢</mo>" : "<mo>⁢</mo>"
|
183
|
+
end
|
184
|
+
|
172
185
|
def dedup_ids(xml)
|
173
186
|
%w(Unit Dimension Prefix Quantity).each do |t|
|
174
187
|
xml.xpath(".//m:#{t}/@xml:id", "m" => UNITSML_NS).map { |a| a.text }.uniq.each do |v|
|
@@ -187,6 +200,12 @@ module Asciimath2UnitsML
|
|
187
200
|
gsub(/<math>/, "<math xmlns='#{MATHML_NS}'>")
|
188
201
|
end
|
189
202
|
|
203
|
+
def embeddedmathml(mathml)
|
204
|
+
x = Nokogiri::XML(mathml)
|
205
|
+
x.xpath(".//m:mi", "m" => MATHML_NS).each { |mi| mi["mathvariant"] = "normal" }
|
206
|
+
x.children.to_xml
|
207
|
+
end
|
208
|
+
|
190
209
|
def ambig_units
|
191
210
|
u = @units_id.each_with_object({}) do |(k, v), m|
|
192
211
|
v.symbolids.each do |x|
|
@@ -10,6 +10,7 @@ module Asciimath2UnitsML
|
|
10
10
|
{ html: HTMLEntities.new.encode(x), mathml: "<mo>#{HTMLEntities.new.encode(x)}</mo>" }
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
13
14
|
def render(unit, style)
|
14
15
|
@symbols[unit][style] || unit
|
15
16
|
end
|
@@ -17,33 +18,56 @@ module Asciimath2UnitsML
|
|
17
18
|
def htmlsymbol(units, normalise)
|
18
19
|
units.map do |u|
|
19
20
|
if u[:multiplier] then u[:multiplier] == "*" ? @multiplier[:html] : u[:multiplier]
|
21
|
+
elsif u[:unit].nil? && u[:prefix]
|
22
|
+
@prefixes[u[:prefix]].html
|
20
23
|
else
|
21
|
-
u[:
|
22
|
-
|
23
|
-
"#{u[:prefix]}#{base}#{exp}"
|
24
|
+
base = (u[:prefix] || "") + render(normalise ? @units[u[:unit]].symbolid : u[:unit], :html)
|
25
|
+
htmlsymbol_exponent(u, base)
|
24
26
|
end
|
25
27
|
end.join("")
|
26
28
|
end
|
27
29
|
|
30
|
+
def htmlsymbol_exponent(u, base)
|
31
|
+
if u[:display_exponent] == "0.5"
|
32
|
+
base = "√#{base}"
|
33
|
+
elsif u[:display_exponent]
|
34
|
+
exp = "<sup>#{u[:display_exponent].sub(/-/, "−")}</sup>"
|
35
|
+
base += exp
|
36
|
+
end
|
37
|
+
base
|
38
|
+
end
|
39
|
+
|
28
40
|
def mathmlsymbol(units, normalise)
|
29
41
|
exp = units.map do |u|
|
30
42
|
if u[:multiplier] then u[:multiplier] == "*" ? @multiplier[:mathml] : "<mo>#{u[:multiplier]}</mo>"
|
43
|
+
elsif u[:unit].nil? && u[:prefix]
|
44
|
+
%(<mi mathvariant='normal'>#{@prefixes[u[:prefix]].html}</mi>)
|
31
45
|
else
|
32
|
-
|
33
|
-
if u[:prefix]
|
34
|
-
base = base.match(/<mi mathvariant='normal'>/) ?
|
35
|
-
base.sub(/<mi mathvariant='normal'>/, "<mi mathvariant='normal'>#{u[:prefix]}") :
|
36
|
-
"<mrow><mi mathvariant='normal'>#{u[:prefix]}#{base}</mrow>"
|
37
|
-
end
|
38
|
-
if u[:display_exponent]
|
39
|
-
exp = "<mn>#{u[:display_exponent]}</mn>".sub(/<mn>-/, "<mo>−</mo><mn>")
|
40
|
-
base = "<msup><mrow>#{base}</mrow><mrow>#{exp}</mrow></msup>"
|
41
|
-
end
|
42
|
-
base
|
46
|
+
mathmlsymbol1(u, normalise)
|
43
47
|
end
|
44
48
|
end.join("")
|
45
49
|
end
|
46
50
|
|
51
|
+
def mathmlsymbol1(u, normalise)
|
52
|
+
base = render(normalise ? @units[u[:unit]].symbolid : u[:unit], :mathml)
|
53
|
+
if u[:prefix]
|
54
|
+
base = base.match(/<mi mathvariant='normal'>/) ?
|
55
|
+
base.sub(/<mi mathvariant='normal'>/, "<mi mathvariant='normal'>#{u[:prefix]}") :
|
56
|
+
"<mrow><mi mathvariant='normal'>#{u[:prefix]}#{base}</mrow>"
|
57
|
+
end
|
58
|
+
mathmlsymbol_exponent(u, base)
|
59
|
+
end
|
60
|
+
|
61
|
+
def mathmlsymbol_exponent(u, base)
|
62
|
+
if u[:display_exponent] == "0.5"
|
63
|
+
base = "<msqrt>#{base}</msqrt>"
|
64
|
+
elsif u[:display_exponent]
|
65
|
+
exp = "<mn>#{u[:display_exponent]}</mn>".sub(/<mn>-/, "<mo>−</mo><mn>")
|
66
|
+
base = "<msup><mrow>#{base}</mrow><mrow>#{exp}</mrow></msup>"
|
67
|
+
end
|
68
|
+
base
|
69
|
+
end
|
70
|
+
|
47
71
|
def mathmlsymbolwrap(units, normalise)
|
48
72
|
<<~END
|
49
73
|
<math xmlns='#{MATHML_NS}'><mrow>#{mathmlsymbol(units, normalise)}</mrow></math>
|
@@ -6,11 +6,12 @@ module Asciimath2UnitsML
|
|
6
6
|
|
7
7
|
def unit_id(text)
|
8
8
|
text = text.gsub(/[()]/, "")
|
9
|
-
"
|
10
|
-
|
9
|
+
/-$/.match(text) and return @prefixes[text.sub(/-$/, "")].id
|
10
|
+
"U_" + (@units[text] ? @units[text].id : text.gsub(/\*/, ".").gsub(/\^/, ""))
|
11
11
|
end
|
12
12
|
|
13
13
|
def unit(units, origtext, normtext, dims, name)
|
14
|
+
return if units_only(units).any? { |x| x[:unit].nil? }
|
14
15
|
dimid = dim_id(dims)
|
15
16
|
norm_units = normalise_units(units)
|
16
17
|
<<~END
|
@@ -34,6 +35,7 @@ module Asciimath2UnitsML
|
|
34
35
|
|
35
36
|
# kg exception
|
36
37
|
def unitsystem(units)
|
38
|
+
return if units_only(units).any? { |x| x[:unit].nil? }
|
37
39
|
ret = []
|
38
40
|
units = units_only(units)
|
39
41
|
units.any? { |x| @units[x[:unit]].system_name != "SI" } and
|
@@ -64,6 +66,7 @@ module Asciimath2UnitsML
|
|
64
66
|
end
|
65
67
|
|
66
68
|
def rootunits(units)
|
69
|
+
return if units_only(units).any? { |x| x[:unit].nil? }
|
67
70
|
return if units.size == 1 && !units[0][:prefix]
|
68
71
|
exp = units_only(units).map do |u|
|
69
72
|
prefix = " prefix='#{u[:prefix]}'" if u[:prefix]
|
data/lib/unitsdb/quantities.yaml
CHANGED
@@ -2437,3 +2437,24 @@ NISTq43:
|
|
2437
2437
|
quantity_type: derived
|
2438
2438
|
quantity_name:
|
2439
2439
|
- organ dose equivalent
|
2440
|
+
|
2441
|
+
NISTq1000:
|
2442
|
+
dimension_url: "#NISTd85"
|
2443
|
+
quantity_type: derived
|
2444
|
+
quantity_name:
|
2445
|
+
- mass fraction
|
2446
|
+
- mole fraction
|
2447
|
+
unit_reference:
|
2448
|
+
- name: parts per million
|
2449
|
+
url: "#NISTu400"
|
2450
|
+
|
2451
|
+
NISTq1001:
|
2452
|
+
dimension_url: "#NISTd16"
|
2453
|
+
quantity_type: derived
|
2454
|
+
quantity_name:
|
2455
|
+
- apparent power
|
2456
|
+
unit_reference:
|
2457
|
+
- name: var
|
2458
|
+
url: "#NISTu401"
|
2459
|
+
|
2460
|
+
|
data/lib/unitsdb/units.yaml
CHANGED
@@ -4372,6 +4372,12 @@
|
|
4372
4372
|
mathml: "<mi mathvariant='normal'>″</mi>"
|
4373
4373
|
latex: \ensuremath{\mathrm{''}}
|
4374
4374
|
unicode: "″"
|
4375
|
+
- id: "as"
|
4376
|
+
ascii: "as"
|
4377
|
+
html: "as"
|
4378
|
+
mathml: "<mi mathvariant='normal'>as</mi>"
|
4379
|
+
latex: \ensuremath{\mathrm{as}}
|
4380
|
+
unicode: "as"
|
4375
4381
|
root_units:
|
4376
4382
|
enumerated_root_units:
|
4377
4383
|
- unit: "arc_second"
|
@@ -6543,6 +6549,12 @@
|
|
6543
6549
|
mathml: "<msub><mrow><mi mathvariant='normal'>cal</mi></mrow><mrow><mi mathvariant='normal'>th</mi></mrow></msub>"
|
6544
6550
|
latex: \ensuremath{\mathrm{cal_th}}
|
6545
6551
|
unicode: "cal_th"
|
6552
|
+
- id: "cal"
|
6553
|
+
ascii: "cal"
|
6554
|
+
html: "cal"
|
6555
|
+
mathml: "<mi mathvariant='normal'>cal</mi>"
|
6556
|
+
latex: \ensuremath{\mathrm{cal}}
|
6557
|
+
unicode: "cal"
|
6546
6558
|
root_units:
|
6547
6559
|
enumerated_root_units:
|
6548
6560
|
- unit: "thermo_calorie"
|
@@ -10620,3 +10632,61 @@
|
|
10620
10632
|
- name: "length"
|
10621
10633
|
url: "#NISTq1"
|
10622
10634
|
|
10635
|
+
"NISTu400":
|
10636
|
+
dimension_url: "#NISTd85"
|
10637
|
+
short:
|
10638
|
+
root: false
|
10639
|
+
unit_system:
|
10640
|
+
type: "SI_derived_non-special"
|
10641
|
+
name: "SI"
|
10642
|
+
unit_name:
|
10643
|
+
- "parts per million"
|
10644
|
+
unit_symbols:
|
10645
|
+
- id: "ppm"
|
10646
|
+
ascii: "ppm"
|
10647
|
+
html: "ppm"
|
10648
|
+
mathml: "<mi mathvariant='normal'>ppm</mi>"
|
10649
|
+
latex: \ensuremath{\mathrm{ppm}}
|
10650
|
+
unicode: "ppm"
|
10651
|
+
quantity_reference:
|
10652
|
+
- name: "mass quantity"
|
10653
|
+
url: "#NISTq1000"
|
10654
|
+
|
10655
|
+
"NISTu401":
|
10656
|
+
dimension_url: "#NISTd16"
|
10657
|
+
short: var
|
10658
|
+
root: true
|
10659
|
+
unit_system:
|
10660
|
+
type: "SI_derived_non-special"
|
10661
|
+
name: "SI"
|
10662
|
+
unit_name:
|
10663
|
+
- "var"
|
10664
|
+
unit_symbols:
|
10665
|
+
- id: "var"
|
10666
|
+
ascii: "var"
|
10667
|
+
html: "var"
|
10668
|
+
mathml: "<mi mathvariant='normal'>var</mi>"
|
10669
|
+
latex: \ensuremath{\mathrm{var}}
|
10670
|
+
unicode: "var"
|
10671
|
+
root_units:
|
10672
|
+
enumerated_root_units:
|
10673
|
+
- unit: "volt"
|
10674
|
+
power_denominator: 1
|
10675
|
+
power_numerator: 1
|
10676
|
+
- unit: "ampere"
|
10677
|
+
power_denominator: 1
|
10678
|
+
power_numerator: 1
|
10679
|
+
quantity_reference:
|
10680
|
+
- name: "apparent power"
|
10681
|
+
url: "#NISTq1001"
|
10682
|
+
si_derived_bases:
|
10683
|
+
- id: NISTu1
|
10684
|
+
prefix:
|
10685
|
+
power: 2
|
10686
|
+
- id: NISTu27
|
10687
|
+
prefix: p10_3
|
10688
|
+
power: 1
|
10689
|
+
- id: NISTu3
|
10690
|
+
prefix:
|
10691
|
+
power: -3
|
10692
|
+
|
data/spec/conv_spec.rb
CHANGED
@@ -106,6 +106,96 @@ RSpec.describe Asciimath2UnitsML do
|
|
106
106
|
OUTPUT
|
107
107
|
end
|
108
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'>⁢</mo>
|
116
|
+
<mrow xref='U_NISTu5'>
|
117
|
+
<mi mathvariant='normal'>°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>⁢</mo>
|
140
|
+
<mrow xref='U_NISTu147'>
|
141
|
+
<mi mathvariant='normal'>′</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'>′</UnitSymbol>
|
147
|
+
<UnitSymbol type='MathML'>
|
148
|
+
<math xmlns='http://www.w3.org/1998/Math/MathML'>
|
149
|
+
<mrow>
|
150
|
+
<mi mathvariant='normal'>′</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'>⁢</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'>√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
|
+
|
109
199
|
it "deals with kg and g" do
|
110
200
|
expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
|
111
201
|
1 "unitsml(kg)" + 1 "unitsml(g)"
|
@@ -359,6 +449,34 @@ INPUT
|
|
359
449
|
OUTPUT
|
360
450
|
end
|
361
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
|
362
480
|
|
363
481
|
it "deals with units division" do
|
364
482
|
expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
|
@@ -695,6 +813,73 @@ OUTPUT
|
|
695
813
|
OUTPUT
|
696
814
|
end
|
697
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'>⁢</mo>
|
823
|
+
<mrow xref='U_mW.cm-2'>
|
824
|
+
<mi mathvariant='normal'>mW</mi>
|
825
|
+
<mo>·</mo>
|
826
|
+
<msup>
|
827
|
+
<mrow>
|
828
|
+
<mi mathvariant='normal'>cm</mi>
|
829
|
+
</mrow>
|
830
|
+
<mrow>
|
831
|
+
<mo>−</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·cm
|
841
|
+
<sup>−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>·</mo>
|
848
|
+
<msup>
|
849
|
+
<mrow>
|
850
|
+
<mi mathvariant='normal'>cm</mi>
|
851
|
+
</mrow>
|
852
|
+
<mrow>
|
853
|
+
<mo>−</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
|
+
|
698
883
|
it "deals with quantity input" do
|
699
884
|
expect(xmlpp(Asciimath2UnitsML::Conv.new().Asciimath2UnitsML(<<~INPUT))).to be_equivalent_to xmlpp(<<~OUTPUT)
|
700
885
|
9 "unitsml(m, quantity: NISTq103)"
|
@@ -803,5 +988,96 @@ INPUT
|
|
803
988
|
OUTPUT
|
804
989
|
end
|
805
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'>⁢</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'>⁢</mo>
|
1022
|
+
<mrow xref='U_cm.s-2'>
|
1023
|
+
<math>
|
1024
|
+
<mi mathvariant='normal'>c</mi>
|
1025
|
+
<mi mathvariant='normal'>m</mi>
|
1026
|
+
<mo>⋅</mo>
|
1027
|
+
<msup>
|
1028
|
+
<mrow>
|
1029
|
+
<mi mathvariant='normal'>s</mi>
|
1030
|
+
</mrow>
|
1031
|
+
<mrow>
|
1032
|
+
<mo>−</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·s
|
1043
|
+
<sup>−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>·</mo>
|
1050
|
+
<msup>
|
1051
|
+
<mrow>
|
1052
|
+
<mi mathvariant='normal'>s</mi>
|
1053
|
+
</mrow>
|
1054
|
+
<mrow>
|
1055
|
+
<mo>−</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
|
+
|
806
1082
|
|
807
1083
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciimath2unitsml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciimath
|