asciimath2unitsml 0.2.0 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +20 -1
- data/lib/asciimath2unitsml/conv.rb +28 -8
- data/lib/asciimath2unitsml/parse.rb +31 -20
- data/lib/asciimath2unitsml/render.rb +47 -16
- data/lib/asciimath2unitsml/unit.rb +5 -2
- data/lib/asciimath2unitsml/version.rb +1 -1
- data/lib/unitsdb/dimensions.yaml +31 -31
- data/lib/unitsdb/quantities.yaml +47 -19
- data/lib/unitsdb/units.yaml +96 -216
- data/lib/unitsdb_ruby/unitsdb.rb +1 -0
- data/spec/conv_spec.rb +510 -4
- 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: 9c5ec436a8b058ce5c93dc246a8493d88a724c7d5f1048b8e42f7a1429791d3c
|
4
|
+
data.tar.gz: a7106b478a1efa4f48c0133c9b644d77197db0d71031d48152274c9c43dde1f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9fd0281fea82d844d833ae155875ab1b52d22cf384185a32330ed18709759aee6df93fb281e0b7844fe14bd79200211646d37b0152a0190a32b81d8d0176153
|
7
|
+
data.tar.gz: 8cee75e492900a7ac7e622134feb3c1f0e10503af231af87c7f55d01c88aaf9d817ed66f753249ac5fe5c355a1de9963f3e6b3ed21379996335c89efccc9d022
|
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,15 @@ 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
|
+
* `unitsml(unit-string, multiplier: SYMBOL)` provides an alternate symbol for the multiliper of
|
57
|
+
units. The options are an XML entity, or the values `space` or `nospace` (for which see discussion under _Usage_).
|
58
|
+
|
59
|
+
Standalone prefixes can be recognised by replacing the unit with hyphen; so `unitsml(p-)` corresponds
|
60
|
+
to the standalone prefix "pico" (and is rendered as "p").
|
46
61
|
|
47
62
|
== Rendering
|
48
63
|
|
@@ -54,6 +69,9 @@ The gem follows the MathML Units convention of inserting a spacing invisible tim
|
|
54
69
|
(`<mo rspace='thickmathspace'>⁢</mo>`) between any numbers (`<mn>`) and unit expressions
|
55
70
|
in MathML, and representing units in MathML as non-italic variables (`<mi mathvariant='normal'>`).
|
56
71
|
|
72
|
+
Space is not inserted between a number and a unit expression, when that unit expression wholly consists
|
73
|
+
of punctuation: _1 m_, _1 °C_, but _9° 7′ 22″_.
|
74
|
+
|
57
75
|
== Example
|
58
76
|
|
59
77
|
[source]
|
@@ -214,7 +232,7 @@ This table can be generated (in Asciidoc format) through `Asciimath2UnitsML::Con
|
|
214
232
|
| ton | ton of TNT (energy equivalent): `ton_TNT` | ton of refrigeration (12 000 Btu_IT/h): `ton_refrigeration` | | | |
|
215
233
|
| tsp | teaspoon: `tsp` | teaspoon (FDA): `tsp_label` | | | |
|
216
234
|
| yd | yard: `yd` | yard (based on US survey foot): `yd_US_survey` | | | |
|
217
|
-
| &#
|
235
|
+
| ° | degree (degree of arc): `deg` | | | | |
|
218
236
|
| γ | gamma: `gamma` | | | | |
|
219
237
|
| μ | micron: `micron` | | | | |
|
220
238
|
| Ω | ohm: `Ohm` | | | | |
|
@@ -242,3 +260,4 @@ This table can be generated (in Asciidoc format) through `Asciimath2UnitsML::Con
|
|
242
260
|
| °R | degree Rankine: `degR` | | | | |
|
243
261
|
| ƛ~C~ | natural unit of length: `lambda-bar_C` | | | | |
|
244
262
|
|===
|
263
|
+
|
@@ -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
|
@@ -44,7 +48,7 @@ module Asciimath2UnitsML
|
|
44
48
|
<PrefixSymbol type="ASCII">#{@prefixes[p].ascii}</PrefixSymbol>
|
45
49
|
<PrefixSymbol type="unicode">#{@prefixes[p].unicode}</PrefixSymbol>
|
46
50
|
<PrefixSymbol type="LaTeX">#{@prefixes[p].latex}</PrefixSymbol>
|
47
|
-
<PrefixSymbol type="HTML">#{
|
51
|
+
<PrefixSymbol type="HTML">#{htmlent @prefixes[p].html}</PrefixSymbol>
|
48
52
|
</Prefix>
|
49
53
|
END
|
50
54
|
end.join("\n")
|
@@ -59,9 +63,22 @@ module Asciimath2UnitsML
|
|
59
63
|
END
|
60
64
|
end
|
61
65
|
|
66
|
+
U2D = {
|
67
|
+
"m" => { dimension: "Length", order: 1, symbol: "L" },
|
68
|
+
"g" => { dimension: "Mass", order: 2, symbol: "M" },
|
69
|
+
"kg" => { dimension: "Mass", order: 2, symbol: "M" },
|
70
|
+
"s" => { dimension: "Time", order: 3, symbol: "T" },
|
71
|
+
"A" => { dimension: "ElectricCurrent", order: 4, symbol: "I" },
|
72
|
+
"K" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" },
|
73
|
+
"degK" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" },
|
74
|
+
"mol" => { dimension: "AmountOfSubstance", order: 6, symbol: "N" },
|
75
|
+
"cd" => { dimension: "LuminousIntensity", order: 7, symbol: "J" },
|
76
|
+
"deg" => { dimension: "PlaneAngle", order: 8, symbol: "Phi" },
|
77
|
+
}.freeze
|
78
|
+
|
62
79
|
def units2dimensions(units)
|
63
80
|
norm = decompose_units(units)
|
64
|
-
return if norm.any? { |u| u[:unit] == "unknown" || u[:prefix] == "unknown" }
|
81
|
+
return if norm.any? { |u| u[:unit] == "unknown" || u[:prefix] == "unknown" || u[:unit].nil? }
|
65
82
|
norm.map do |u|
|
66
83
|
{ dimension: U2D[u[:unit]][:dimension],
|
67
84
|
unit: u[:unit],
|
@@ -71,7 +88,7 @@ module Asciimath2UnitsML
|
|
71
88
|
end
|
72
89
|
|
73
90
|
def dimension1(u)
|
74
|
-
%(<#{u[:dimension]} symbol="#{u[:symbol]}" powerNumerator="#{u[:exponent]}"/>)
|
91
|
+
%(<#{u[:dimension]} symbol="#{u[:symbol]}" powerNumerator="#{float_to_display(u[:exponent])}"/>)
|
75
92
|
end
|
76
93
|
|
77
94
|
def dim_id(dims)
|
@@ -81,7 +98,9 @@ module Asciimath2UnitsML
|
|
81
98
|
AmountOfSubstance LuminousIntensity PlaneAngle)
|
82
99
|
.map { |h| dimhash.dig(h, :exponent) }.join(":")
|
83
100
|
id = @dimensions_id&.values&.select { |d| d.vector == dimsvector }&.first&.id and return id.to_s
|
84
|
-
"D_" + dims.map
|
101
|
+
"D_" + dims.map do |d|
|
102
|
+
U2D[d[:unit]][:symbol] + (d[:exponent] == 1 ? "" : float_to_display(d[:exponent]))
|
103
|
+
end.join("")
|
85
104
|
end
|
86
105
|
|
87
106
|
def decompose_units(units)
|
@@ -94,7 +113,7 @@ module Asciimath2UnitsML
|
|
94
113
|
else
|
95
114
|
m[-1] = { prefix: combine_prefixes(@prefixes[m[-1][:prefix]], @prefixes[k[:prefix]]),
|
96
115
|
unit: m[-1][:unit],
|
97
|
-
exponent: (k[:exponent]&.
|
116
|
+
exponent: (k[:exponent]&.to_f || 1) + (m[-1][:exponent]&.to_f || 1) }
|
98
117
|
end
|
99
118
|
end
|
100
119
|
end
|
@@ -102,7 +121,8 @@ module Asciimath2UnitsML
|
|
102
121
|
# treat g not kg as base unit: we have stripped the prefix k in parsing
|
103
122
|
# reduce units down to basic units
|
104
123
|
def decompose_unit(u)
|
105
|
-
if u[:unit]
|
124
|
+
if u[:unit].nil? then u
|
125
|
+
elsif u[:unit] == "g" then u
|
106
126
|
elsif @units[u[:unit]].system_type == "SI_base" then u
|
107
127
|
elsif !@units[u[:unit]].si_derived_bases
|
108
128
|
{ prefix: u[:prefix], unit: "unknown", exponent: u[:exponent] }
|
@@ -111,7 +131,7 @@ module Asciimath2UnitsML
|
|
111
131
|
m << { prefix: !k[:prefix].nil? && !k[:prefix].empty? ?
|
112
132
|
combine_prefixes(@prefixes_id[k[:prefix]], @prefixes[u[:prefix]]) : u[:prefix],
|
113
133
|
unit: @units_id[k[:id]].symbolid,
|
114
|
-
exponent: (k[:power]&.to_i || 1) * (u[:exponent]&.
|
134
|
+
exponent: (k[:power]&.to_i || 1) * (u[:exponent]&.to_f || 1) }
|
115
135
|
end
|
116
136
|
end
|
117
137
|
end
|
@@ -121,7 +141,7 @@ module Asciimath2UnitsML
|
|
121
141
|
return p1.symbolid if p2.nil?
|
122
142
|
return p2.symbolid if p1.nil?
|
123
143
|
return "unknown" if p1.base != p2.base
|
124
|
-
@prefixes.each do |p|
|
144
|
+
@prefixes.each do |_, p|
|
125
145
|
return p.symbolid if p.base == p1.base && p.power == p1.power + p2.power
|
126
146
|
end
|
127
147
|
"unknown"
|
@@ -87,19 +87,24 @@ module Asciimath2UnitsML
|
|
87
87
|
prefix2 = /#{@prefixes.keys.select { |x| x.size == 2 }.join("|")}/.r
|
88
88
|
prefix1 = /#{@prefixes.keys.select { |x| x.size == 1 }.join("|")}/.r
|
89
89
|
unit_keys = @units.keys.reject do |k|
|
90
|
-
|
90
|
+
/\*|\^|\/|^1$/.match(k) || @units[k].prefixed
|
91
91
|
end.map { |k| Regexp.escape(k) }
|
92
92
|
unit1 = /#{unit_keys.sort_by(&:length).reverse.join("|")}/.r
|
93
93
|
exponent = /\^\(-?\d+\)/.r.map { |m| m.sub(/\^/, "").gsub(/[()]/, "") } |
|
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,13 @@ 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*/, "")
|
126
|
+
multiplier = text[1..-1]&.select { |x| /^multiplier:/.match(x) }&.first&.sub(/^multiplier:\s*/, "")
|
120
127
|
normtext = units_only(units).each.map do |u|
|
121
128
|
exp = u[:exponent] && u[:exponent] != "1" ? "^#{u[:exponent]}" : ""
|
122
129
|
"#{u[:prefix]}#{u[:unit]}#{exp}"
|
123
130
|
end.join("*")
|
124
|
-
[units, text[0], normtext, quantity, name]
|
131
|
+
[units, text[0], normtext, quantity, name, symbol, multiplier]
|
125
132
|
end
|
126
133
|
|
127
134
|
def postprocess1(units)
|
@@ -137,19 +144,6 @@ module Asciimath2UnitsML
|
|
137
144
|
end
|
138
145
|
end
|
139
146
|
|
140
|
-
U2D = {
|
141
|
-
"m" => { dimension: "Length", order: 1, symbol: "L" },
|
142
|
-
"g" => { dimension: "Mass", order: 2, symbol: "M" },
|
143
|
-
"kg" => { dimension: "Mass", order: 2, symbol: "M" },
|
144
|
-
"s" => { dimension: "Time", order: 3, symbol: "T" },
|
145
|
-
"A" => { dimension: "ElectricCurrent", order: 4, symbol: "I" },
|
146
|
-
"K" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" },
|
147
|
-
"degK" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" },
|
148
|
-
"mol" => { dimension: "AmountOfSubstance", order: 6, symbol: "N" },
|
149
|
-
"cd" => { dimension: "LuminousIntensity", order: 7, symbol: "J" },
|
150
|
-
"deg" => { dimension: "PlaneAngle", order: 8, symbol: "Phi" },
|
151
|
-
}
|
152
|
-
|
153
147
|
def Asciimath2UnitsML(expression)
|
154
148
|
xml = Nokogiri::XML(asciimath2mathml(expression))
|
155
149
|
MathML2UnitsML(xml).to_xml
|
@@ -161,14 +155,25 @@ module Asciimath2UnitsML
|
|
161
155
|
xml.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
|
162
156
|
next unless %r{^unitsml\(.+\)$}.match(x.text)
|
163
157
|
text = x.text.sub(%r{^unitsml\((.+)\)$}m, "\\1")
|
164
|
-
units, origtext, normtext, quantity, name = parse(text)
|
165
|
-
|
166
|
-
|
158
|
+
units, origtext, normtext, quantity, name, symbol, multiplier = parse(text)
|
159
|
+
rendering = symbol ? embeddedmathml(asciimath2mathml(symbol)) :
|
160
|
+
mathmlsymbol(units, false, multiplier)
|
161
|
+
x.replace("#{delimspace(rendering, x)}<mrow xref='#{unit_id(origtext)}'>#{rendering}</mrow>\n"\
|
167
162
|
"#{unitsml(units, origtext, normtext, quantity, name)}")
|
168
163
|
end
|
169
164
|
dedup_ids(xml)
|
170
165
|
end
|
171
166
|
|
167
|
+
# if previous sibling's last descendent non-whitespace is MathML and mn or mi, no space
|
168
|
+
def delimspace(rendering, elem)
|
169
|
+
prec_text_elem = elem.xpath("./preceding-sibling::*[namespace-uri() = '#{MATHML_NS}']/"\
|
170
|
+
"descendant::text()[normalize-space()!=''][last()]/parent::*").last
|
171
|
+
return "" if prec_text_elem.nil? || !%w(mn mi).include?(prec_text_elem&.name)
|
172
|
+
text = HTMLEntities.new.encode(Nokogiri::XML("<mrow>#{rendering}</mrow>").text.strip)
|
173
|
+
/\p{L}|\p{N}/.match(text) ?
|
174
|
+
"<mo rspace='thickmathspace'>⁢</mo>" : "<mo>⁢</mo>"
|
175
|
+
end
|
176
|
+
|
172
177
|
def dedup_ids(xml)
|
173
178
|
%w(Unit Dimension Prefix Quantity).each do |t|
|
174
179
|
xml.xpath(".//m:#{t}/@xml:id", "m" => UNITSML_NS).map { |a| a.text }.uniq.each do |v|
|
@@ -187,6 +192,12 @@ module Asciimath2UnitsML
|
|
187
192
|
gsub(/<math>/, "<math xmlns='#{MATHML_NS}'>")
|
188
193
|
end
|
189
194
|
|
195
|
+
def embeddedmathml(mathml)
|
196
|
+
x = Nokogiri::XML(mathml)
|
197
|
+
x.xpath(".//m:mi", "m" => MATHML_NS).each { |mi| mi["mathvariant"] = "normal" }
|
198
|
+
x.children.to_xml
|
199
|
+
end
|
200
|
+
|
190
201
|
def ambig_units
|
191
202
|
u = @units_id.each_with_object({}) do |(k, v), m|
|
192
203
|
v.symbolids.each do |x|
|
@@ -10,40 +10,71 @@ 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
|
16
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
|
+
|
17
23
|
def htmlsymbol(units, normalise)
|
18
24
|
units.map do |u|
|
19
25
|
if u[:multiplier] then u[:multiplier] == "*" ? @multiplier[:html] : u[:multiplier]
|
26
|
+
elsif u[:unit].nil? && u[:prefix]
|
27
|
+
@prefixes[u[:prefix]].html
|
20
28
|
else
|
21
|
-
u[:
|
22
|
-
|
23
|
-
"#{u[:prefix]}#{base}#{exp}"
|
29
|
+
base = (u[:prefix] || "") + render(normalise ? @units[u[:unit]].symbolid : u[:unit], :html)
|
30
|
+
htmlsymbol_exponent(u, base)
|
24
31
|
end
|
25
32
|
end.join("")
|
26
33
|
end
|
27
34
|
|
28
|
-
def
|
35
|
+
def htmlsymbol_exponent(u, base)
|
36
|
+
if u[:display_exponent] == "0.5"
|
37
|
+
base = "√#{base}"
|
38
|
+
elsif u[:display_exponent]
|
39
|
+
exp = "<sup>#{u[:display_exponent].sub(/-/, "−")}</sup>"
|
40
|
+
base += exp
|
41
|
+
end
|
42
|
+
base
|
43
|
+
end
|
44
|
+
|
45
|
+
def mathmlsymbol(units, normalise, multiplier = nil)
|
46
|
+
multiplier = multiplier ? "<mo>#{multiplier}</mo>" : @multiplier[:mathml]
|
29
47
|
exp = units.map do |u|
|
30
|
-
if u[:multiplier] then u[:multiplier] == "*" ?
|
48
|
+
if u[:multiplier] then u[:multiplier] == "*" ? multiplier : "<mo>#{u[:multiplier]}</mo>"
|
49
|
+
elsif u[:unit].nil? && u[:prefix]
|
50
|
+
%(<mi mathvariant='normal'>#{htmlent(@prefixes[u[:prefix]].html)}</mi>)
|
31
51
|
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
|
52
|
+
mathmlsymbol1(u, normalise)
|
43
53
|
end
|
44
54
|
end.join("")
|
45
55
|
end
|
46
56
|
|
57
|
+
def mathmlsymbol1(u, normalise)
|
58
|
+
base = render(normalise ? @units[u[:unit]].symbolid : u[:unit], :mathml)
|
59
|
+
if u[:prefix]
|
60
|
+
prefix = htmlent(@prefixes[u[:prefix]].html)
|
61
|
+
base = base.match(/<mi mathvariant='normal'>/) ?
|
62
|
+
base.sub(/<mi mathvariant='normal'>/, "<mi mathvariant='normal'>#{prefix}") :
|
63
|
+
"<mrow><mi mathvariant='normal'>#{prefix}#{base}</mrow>"
|
64
|
+
end
|
65
|
+
mathmlsymbol_exponent(u, base)
|
66
|
+
end
|
67
|
+
|
68
|
+
def mathmlsymbol_exponent(u, base)
|
69
|
+
if u[:display_exponent] == "0.5"
|
70
|
+
base = "<msqrt>#{base}</msqrt>"
|
71
|
+
elsif u[:display_exponent]
|
72
|
+
exp = "<mn>#{u[:display_exponent]}</mn>".sub(/<mn>-/, "<mo>−</mo><mn>")
|
73
|
+
base = "<msup><mrow>#{base}</mrow><mrow>#{exp}</mrow></msup>"
|
74
|
+
end
|
75
|
+
base
|
76
|
+
end
|
77
|
+
|
47
78
|
def mathmlsymbolwrap(units, normalise)
|
48
79
|
<<~END
|
49
80
|
<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.gsub(/'/, "_") : 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/dimensions.yaml
CHANGED
@@ -753,50 +753,50 @@ NISTd75:
|
|
753
753
|
powerNumerator: 1
|
754
754
|
symbol: I
|
755
755
|
|
756
|
-
NISTd85:
|
757
|
-
|
756
|
+
#NISTd85:
|
757
|
+
#dimensionless: true
|
758
758
|
|
759
|
-
NISTd84:
|
760
|
-
|
759
|
+
#NISTd84:
|
760
|
+
#dimensionless: true
|
761
761
|
|
762
|
-
NISTd87:
|
763
|
-
|
762
|
+
#NISTd87:
|
763
|
+
#dimensionless: true
|
764
764
|
|
765
|
-
NISTd86:
|
766
|
-
|
765
|
+
#NISTd86:
|
766
|
+
#dimensionless: true
|
767
767
|
|
768
|
-
NISTd81:
|
769
|
-
|
768
|
+
#NISTd81:
|
769
|
+
#dimensionless: true
|
770
770
|
|
771
771
|
NISTd80:
|
772
|
-
|
772
|
+
dimensionless: true
|
773
773
|
|
774
|
-
NISTd83:
|
775
|
-
|
774
|
+
#NISTd83:
|
775
|
+
#dimensionless: true
|
776
776
|
|
777
|
-
NISTd82:
|
778
|
-
|
777
|
+
#NISTd82:
|
778
|
+
#dimensionless: true
|
779
779
|
|
780
|
-
NISTd95:
|
781
|
-
|
780
|
+
#NISTd95:
|
781
|
+
#dimensionless: true
|
782
782
|
|
783
|
-
NISTd94:
|
784
|
-
|
783
|
+
#NISTd94:
|
784
|
+
#dimensionless: true
|
785
785
|
|
786
|
-
NISTd89:
|
787
|
-
|
786
|
+
#NISTd89:
|
787
|
+
#dimensionless: true
|
788
788
|
|
789
|
-
NISTd88:
|
790
|
-
|
789
|
+
#NISTd88:
|
790
|
+
#dimensionless: true
|
791
791
|
|
792
|
-
NISTd91:
|
793
|
-
|
792
|
+
#NISTd91:
|
793
|
+
#dimensionless: true
|
794
794
|
|
795
|
-
NISTd90:
|
796
|
-
|
795
|
+
#NISTd90:
|
796
|
+
#dimensionless: true
|
797
797
|
|
798
|
-
NISTd92:
|
799
|
-
|
798
|
+
#NISTd92:
|
799
|
+
#dimensionless: true
|
800
800
|
|
801
|
-
NISTd93:
|
802
|
-
|
801
|
+
#NISTd93:
|
802
|
+
#dimensionless: true
|