unitsml 0.6.8 → 0.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/unitsml/errors/parg_load_error.rb +12 -0
- data/lib/unitsml/errors.rb +1 -0
- data/lib/unitsml/opal/database_payload.rb +1 -1
- data/lib/unitsml/opal/payload_generator.rb +6 -1
- data/lib/unitsml/opal.rb +2 -3
- data/lib/unitsml/parg/tree_mapper.rb +151 -0
- data/lib/unitsml/parg.rb +7 -0
- data/lib/unitsml/parser.rb +44 -10
- data/lib/unitsml/unitsdb/units.rb +6 -0
- data/lib/unitsml/version.rb +1 -1
- data/lib/unitsml.rb +2 -4
- data/unitsml.gemspec +2 -3
- metadata +21 -35
- data/lib/unitsml/intermediate_exp_rules.rb +0 -86
- data/lib/unitsml/parse.rb +0 -82
- data/lib/unitsml/transform.rb +0 -205
|
@@ -72,8 +72,13 @@ module Unitsml
|
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
# Keys sorted so the output is byte-identical regardless of the
|
|
76
|
+
# hash insertion order the unitsdb/lutaml load path happens to
|
|
77
|
+
# produce on a given Ruby or gem version.
|
|
75
78
|
def serialize_hash(value)
|
|
76
|
-
"{#{value.
|
|
79
|
+
"{#{value.sort_by do |k, _|
|
|
80
|
+
k.to_s
|
|
81
|
+
end.map { |k, v| "#{serialize(k)}=>#{serialize(v)}" }.join(',')}}"
|
|
77
82
|
end
|
|
78
83
|
|
|
79
84
|
def serialize_array(value)
|
data/lib/unitsml/opal.rb
CHANGED
|
@@ -36,6 +36,7 @@ require "unitsml/errors/base_error"
|
|
|
36
36
|
require "unitsml/errors/invalid_model_error"
|
|
37
37
|
require "unitsml/errors/opal_payload_not_bundled_error"
|
|
38
38
|
require "unitsml/errors/plurimath_load_error"
|
|
39
|
+
require "unitsml/errors/parg_load_error"
|
|
39
40
|
require "unitsml/errors/unsupported_payload_type_error"
|
|
40
41
|
|
|
41
42
|
require "unitsml/opal/database_payload"
|
|
@@ -87,15 +88,13 @@ require "unitsml/extender"
|
|
|
87
88
|
require "unitsml/fenced"
|
|
88
89
|
require "unitsml/fenced_numeric"
|
|
89
90
|
require "unitsml/formula"
|
|
90
|
-
require "unitsml/intermediate_exp_rules"
|
|
91
91
|
require "unitsml/mathml_helper"
|
|
92
92
|
require "unitsml/number"
|
|
93
|
-
require "unitsml/
|
|
93
|
+
require "unitsml/parg"
|
|
94
94
|
require "unitsml/parser"
|
|
95
95
|
require "unitsml/prefix"
|
|
96
96
|
require "unitsml/prefix_adapter"
|
|
97
97
|
require "unitsml/sqrt"
|
|
98
|
-
require "unitsml/transform"
|
|
99
98
|
require "unitsml/unit"
|
|
100
99
|
require "unitsml/utility"
|
|
101
100
|
require "unitsml/xml"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unitsml
|
|
4
|
+
module Parg
|
|
5
|
+
# Maps asciiunits artifact parse trees (capture-named hashes whose leaves
|
|
6
|
+
# are {value, offset, ...} slices) onto the same object model the Parslet
|
|
7
|
+
# Transform produces. Dispatch is on the exact key set of each node
|
|
8
|
+
# (sorted), bottom-up, mirroring rule-for-rule the Transform rules in
|
|
9
|
+
# unitsml/transform.rb.
|
|
10
|
+
class TreeMapper
|
|
11
|
+
def apply(tree)
|
|
12
|
+
map(normalize(tree))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# The artifact runtime hands back symbol-keyed hashes with parsanol
|
|
18
|
+
# Slice leaves; the mapper works on string keys and stringified leaves.
|
|
19
|
+
def normalize(node)
|
|
20
|
+
case node
|
|
21
|
+
when Hash then node.to_h { |key, value| [key.to_s, normalize(value)] }
|
|
22
|
+
when Array then node.map { |value| normalize(value) }
|
|
23
|
+
else node
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The case below is a dispatch table mirroring unitsml/transform.rb
|
|
28
|
+
# rule-for-rule; splitting it would obscure the 1:1 parity contract.
|
|
29
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
30
|
+
def map(node)
|
|
31
|
+
return node unless node.is_a?(Hash)
|
|
32
|
+
|
|
33
|
+
node = node.transform_values do |value|
|
|
34
|
+
value.is_a?(Hash) ? map(value) : value
|
|
35
|
+
end
|
|
36
|
+
case node.keys.map(&:to_s).sort
|
|
37
|
+
when %w[dimension] then Dimension.new(text(node["dimension"]))
|
|
38
|
+
when %w[dimension extender power_numerator sequence]
|
|
39
|
+
Formula.new(
|
|
40
|
+
[Dimension.new(text(node["dimension"]), node["power_numerator"]),
|
|
41
|
+
Extender.new(text(node["extender"])),
|
|
42
|
+
node["sequence"]],
|
|
43
|
+
)
|
|
44
|
+
when %w[dimension extender sequence]
|
|
45
|
+
Formula.new(
|
|
46
|
+
[Dimension.new(text(node["dimension"])),
|
|
47
|
+
Extender.new(text(node["extender"])),
|
|
48
|
+
node["sequence"]],
|
|
49
|
+
)
|
|
50
|
+
when %w[dimension power_numerator]
|
|
51
|
+
Dimension.new(text(node["dimension"]), node["power_numerator"])
|
|
52
|
+
when %w[extender first_set second_set]
|
|
53
|
+
Formula.new(
|
|
54
|
+
[node["first_set"], Extender.new(text(node["extender"])),
|
|
55
|
+
node["second_set"]],
|
|
56
|
+
)
|
|
57
|
+
when %w[extender implicit_extended sequence]
|
|
58
|
+
Formula.new(
|
|
59
|
+
[node["implicit_extended"], Extender.new(text(node["extender"])),
|
|
60
|
+
node["sequence"]],
|
|
61
|
+
)
|
|
62
|
+
when %w[extender int_exp sequence]
|
|
63
|
+
Formula.new(
|
|
64
|
+
[node["int_exp"], Extender.new(text(node["extender"])),
|
|
65
|
+
node["sequence"]],
|
|
66
|
+
)
|
|
67
|
+
when %w[extender power_numerator sequence unit]
|
|
68
|
+
Formula.new(
|
|
69
|
+
[Unit.new(text(node["unit"]), node["power_numerator"]),
|
|
70
|
+
Extender.new(text(node["extender"])),
|
|
71
|
+
node["sequence"]],
|
|
72
|
+
)
|
|
73
|
+
when %w[extender power_numerator prefix sequence unit]
|
|
74
|
+
Formula.new(
|
|
75
|
+
[Unit.new(text(node["unit"]), node["power_numerator"],
|
|
76
|
+
prefix: Prefix.new(text(node["prefix"]))),
|
|
77
|
+
Extender.new(text(node["extender"])),
|
|
78
|
+
node["sequence"]],
|
|
79
|
+
)
|
|
80
|
+
when %w[extender prefix sequence unit]
|
|
81
|
+
Formula.new(
|
|
82
|
+
[Unit.new(text(node["unit"]),
|
|
83
|
+
prefix: Prefix.new(text(node["prefix"]))),
|
|
84
|
+
Extender.new(text(node["extender"])),
|
|
85
|
+
node["sequence"]],
|
|
86
|
+
)
|
|
87
|
+
when %w[extender sequence unit]
|
|
88
|
+
Formula.new(
|
|
89
|
+
[Unit.new(text(node["unit"])),
|
|
90
|
+
Extender.new(text(node["extender"])),
|
|
91
|
+
node["sequence"]],
|
|
92
|
+
)
|
|
93
|
+
when %w[first_int_exp_set second_int_exp_set]
|
|
94
|
+
Formula.new(
|
|
95
|
+
[set_to_fence(node["first_int_exp_set"]),
|
|
96
|
+
set_to_fence(node["second_int_exp_set"])],
|
|
97
|
+
)
|
|
98
|
+
when %w[first_int_exp_set second_set]
|
|
99
|
+
Formula.new(
|
|
100
|
+
[set_to_fence(node["first_int_exp_set"]), node["second_set"]],
|
|
101
|
+
)
|
|
102
|
+
when %w[first_set second_int_exp_set]
|
|
103
|
+
Formula.new(
|
|
104
|
+
[node["first_set"], set_to_fence(node["second_int_exp_set"])],
|
|
105
|
+
)
|
|
106
|
+
when %w[first_set second_set]
|
|
107
|
+
Formula.new([node["first_set"], node["second_set"]])
|
|
108
|
+
when %w[implicit_extended] then node["implicit_extended"]
|
|
109
|
+
when %w[int_exp] then node["int_exp"]
|
|
110
|
+
when %w[int_exp sequence]
|
|
111
|
+
Formula.new([node["int_exp"], node["sequence"]])
|
|
112
|
+
when %w[integer] then Number.new(text(node["integer"]))
|
|
113
|
+
when %w[close_paren integer open_paren]
|
|
114
|
+
Fenced.new(text(node["open_paren"]),
|
|
115
|
+
Number.new(text(node["integer"])),
|
|
116
|
+
text(node["close_paren"]))
|
|
117
|
+
when %w[close_paren int_exp open_paren]
|
|
118
|
+
Fenced.new(text(node["open_paren"]), node["int_exp"],
|
|
119
|
+
text(node["close_paren"]))
|
|
120
|
+
when %w[power_numerator unit]
|
|
121
|
+
Unit.new(text(node["unit"]), node["power_numerator"])
|
|
122
|
+
when %w[power_numerator prefix unit]
|
|
123
|
+
Unit.new(text(node["unit"]), node["power_numerator"],
|
|
124
|
+
prefix: Prefix.new(text(node["prefix"])))
|
|
125
|
+
when %w[prefix] then Prefix.new(text(node["prefix"]))
|
|
126
|
+
when %w[prefix unit]
|
|
127
|
+
Unit.new(text(node["unit"]), prefix: Prefix.new(text(node["prefix"])))
|
|
128
|
+
when %w[sqrt] then Sqrt.new(node["sqrt"])
|
|
129
|
+
when %w[unit] then Unit.new(text(node["unit"]))
|
|
130
|
+
else
|
|
131
|
+
# The Parslet Transform leaves unmatched key combinations as raw
|
|
132
|
+
# hashes with symbol keys (e.g. {sqrt:, sequence:}); mirror that.
|
|
133
|
+
# Terminal slices (identifiable by their "value" key) keep their
|
|
134
|
+
# string keys.
|
|
135
|
+
node.key?("value") ? node : node.transform_keys(&:to_sym)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def text(slice)
|
|
140
|
+
slice.is_a?(Hash) ? slice.fetch("value") : slice.to_s
|
|
141
|
+
end
|
|
142
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
143
|
+
|
|
144
|
+
def set_to_fence(set)
|
|
145
|
+
return set if set.is_a?(Fenced)
|
|
146
|
+
|
|
147
|
+
Fenced.new("(", set, ")")
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
data/lib/unitsml/parg.rb
ADDED
data/lib/unitsml/parser.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Unitsml
|
|
4
|
+
# Parses AsciiUnits expressions through the asciiunits PARG artifact
|
|
5
|
+
# (github.com/unitsml/asciiunits) into the Formula object model.
|
|
4
6
|
class Parser
|
|
5
7
|
attr_accessor :text
|
|
6
8
|
|
|
@@ -13,21 +15,42 @@ module Unitsml
|
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def parse
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
formula = Formula.new(
|
|
20
|
-
formula_value,
|
|
21
|
-
explicit_value: @extras_hash,
|
|
22
|
-
root: true,
|
|
23
|
-
orig_text: @orig_text,
|
|
24
|
-
norm_text: text,
|
|
25
|
-
)
|
|
18
|
+
tree = self.class.artifact.parse("expression", text)
|
|
19
|
+
mapped = Parg::TreeMapper.new.apply(tree)
|
|
20
|
+
formula = build_formula(mapped)
|
|
26
21
|
update_units_exponents(formula.value, false)
|
|
27
22
|
formula.value.first.only_instance = true if text.end_with?("-")
|
|
28
23
|
formula
|
|
29
24
|
end
|
|
30
25
|
|
|
26
|
+
class << self
|
|
27
|
+
def artifact
|
|
28
|
+
@artifact ||= load_artifact
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def load_artifact
|
|
34
|
+
if RUBY_ENGINE == "opal"
|
|
35
|
+
raise Errors::PargLoadError.new(
|
|
36
|
+
"the asciiunits gem",
|
|
37
|
+
"the parsanol runtime is not available under Opal; " \
|
|
38
|
+
"use a runtime with native code access",
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Opal's builder statically scans literal requires; neither
|
|
43
|
+
# asciiunits nor parsanol has an Opal build, so keep the requires
|
|
44
|
+
# dynamic (this line never runs under Opal — the RUBY_ENGINE guard
|
|
45
|
+
# above raises first).
|
|
46
|
+
data_gem = "asciiunits"
|
|
47
|
+
require data_gem
|
|
48
|
+
Asciiunits.load_artifact
|
|
49
|
+
rescue LoadError => e
|
|
50
|
+
raise Errors::PargLoadError.new("the asciiunits gem", e.message)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
31
54
|
def update_units_exponents(array, inverse, sqrt = false)
|
|
32
55
|
array.each do |object|
|
|
33
56
|
if object.is_a?(Sqrt)
|
|
@@ -71,6 +94,17 @@ module Unitsml
|
|
|
71
94
|
|
|
72
95
|
private
|
|
73
96
|
|
|
97
|
+
def build_formula(mapped)
|
|
98
|
+
formula_value = mapped.is_a?(Formula) ? mapped.value : [mapped].flatten
|
|
99
|
+
Formula.new(
|
|
100
|
+
formula_value,
|
|
101
|
+
explicit_value: @extras_hash,
|
|
102
|
+
root: true,
|
|
103
|
+
orig_text: @orig_text,
|
|
104
|
+
norm_text: text,
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
|
|
74
108
|
def extract_equation(text)
|
|
75
109
|
return text unless text&.start_with?("unitsml(")
|
|
76
110
|
|
|
@@ -19,6 +19,12 @@ module Unitsml
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def prefixed_symbols
|
|
23
|
+
@prefixed_symbols ||= symbols_ids.select do |unit|
|
|
24
|
+
find_by_symbol_id(unit).prefixed && !%r{\*|\^|/|^1$}.match?(unit)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
22
28
|
def find_by_symbol_id(sym_id)
|
|
23
29
|
symbols_hash[sym_id]
|
|
24
30
|
end
|
data/lib/unitsml/version.rb
CHANGED
data/lib/unitsml.rb
CHANGED
|
@@ -13,17 +13,15 @@ module Unitsml
|
|
|
13
13
|
autoload :Fenced, "unitsml/fenced"
|
|
14
14
|
autoload :FencedNumeric, "unitsml/fenced_numeric"
|
|
15
15
|
autoload :Formula, "unitsml/formula"
|
|
16
|
-
autoload :IntermediateExpRules, "unitsml/intermediate_exp_rules"
|
|
17
16
|
autoload :MathmlHelper, "unitsml/mathml_helper"
|
|
18
17
|
autoload :Model, "unitsml/model"
|
|
19
18
|
autoload :Namespace, "unitsml/namespace"
|
|
20
19
|
autoload :Number, "unitsml/number"
|
|
21
|
-
autoload :
|
|
20
|
+
autoload :Parg, "unitsml/parg"
|
|
22
21
|
autoload :Parser, "unitsml/parser"
|
|
23
22
|
autoload :Prefix, "unitsml/prefix"
|
|
24
23
|
autoload :PrefixAdapter, "unitsml/prefix_adapter"
|
|
25
24
|
autoload :Sqrt, "unitsml/sqrt"
|
|
26
|
-
autoload :Transform, "unitsml/transform"
|
|
27
25
|
autoload :Unit, "unitsml/unit"
|
|
28
26
|
autoload :Unitsdb, "unitsml/unitsdb"
|
|
29
27
|
autoload :Utility, "unitsml/utility"
|
|
@@ -31,6 +29,6 @@ module Unitsml
|
|
|
31
29
|
autoload :Xml, "unitsml/xml"
|
|
32
30
|
|
|
33
31
|
def parse(string)
|
|
34
|
-
|
|
32
|
+
Parser.new(string).parse
|
|
35
33
|
end
|
|
36
34
|
end
|
data/unitsml.gemspec
CHANGED
|
@@ -32,10 +32,9 @@ Gem::Specification.new do |spec|
|
|
|
32
32
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
33
33
|
spec.require_paths = ["lib"]
|
|
34
34
|
|
|
35
|
+
spec.add_dependency "asciiunits", "~> 0.1"
|
|
35
36
|
spec.add_dependency "htmlentities"
|
|
36
37
|
spec.add_dependency "lutaml-model", "~> 0.8.0"
|
|
37
38
|
spec.add_dependency "mml", "~> 2.4.0"
|
|
38
|
-
spec.add_dependency "
|
|
39
|
-
spec.add_dependency "parslet"
|
|
40
|
-
spec.add_dependency "unitsdb", "~> 2.2.4"
|
|
39
|
+
spec.add_dependency "unitsdb", "~> 2.2.5"
|
|
41
40
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: unitsml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: asciiunits
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.1'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.1'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: htmlentities
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -52,48 +66,20 @@ dependencies:
|
|
|
52
66
|
- - "~>"
|
|
53
67
|
- !ruby/object:Gem::Version
|
|
54
68
|
version: 2.4.0
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: ox
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - ">="
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
62
|
-
type: :runtime
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - ">="
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: parslet
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :runtime
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
69
|
- !ruby/object:Gem::Dependency
|
|
84
70
|
name: unitsdb
|
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
|
86
72
|
requirements:
|
|
87
73
|
- - "~>"
|
|
88
74
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 2.2.
|
|
75
|
+
version: 2.2.5
|
|
90
76
|
type: :runtime
|
|
91
77
|
prerelease: false
|
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
79
|
requirements:
|
|
94
80
|
- - "~>"
|
|
95
81
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 2.2.
|
|
82
|
+
version: 2.2.5
|
|
97
83
|
description: Library to work with UnitsML in Ruby
|
|
98
84
|
email:
|
|
99
85
|
- open.source@ribose.com
|
|
@@ -127,13 +113,13 @@ files:
|
|
|
127
113
|
- lib/unitsml/errors/base_error.rb
|
|
128
114
|
- lib/unitsml/errors/invalid_model_error.rb
|
|
129
115
|
- lib/unitsml/errors/opal_payload_not_bundled_error.rb
|
|
116
|
+
- lib/unitsml/errors/parg_load_error.rb
|
|
130
117
|
- lib/unitsml/errors/plurimath_load_error.rb
|
|
131
118
|
- lib/unitsml/errors/unsupported_payload_type_error.rb
|
|
132
119
|
- lib/unitsml/extender.rb
|
|
133
120
|
- lib/unitsml/fenced.rb
|
|
134
121
|
- lib/unitsml/fenced_numeric.rb
|
|
135
122
|
- lib/unitsml/formula.rb
|
|
136
|
-
- lib/unitsml/intermediate_exp_rules.rb
|
|
137
123
|
- lib/unitsml/mathml_helper.rb
|
|
138
124
|
- lib/unitsml/model.rb
|
|
139
125
|
- lib/unitsml/model/dimension.rb
|
|
@@ -166,12 +152,12 @@ files:
|
|
|
166
152
|
- lib/unitsml/opal.rb
|
|
167
153
|
- lib/unitsml/opal/database_payload.rb
|
|
168
154
|
- lib/unitsml/opal/payload_generator.rb
|
|
169
|
-
- lib/unitsml/
|
|
155
|
+
- lib/unitsml/parg.rb
|
|
156
|
+
- lib/unitsml/parg/tree_mapper.rb
|
|
170
157
|
- lib/unitsml/parser.rb
|
|
171
158
|
- lib/unitsml/prefix.rb
|
|
172
159
|
- lib/unitsml/prefix_adapter.rb
|
|
173
160
|
- lib/unitsml/sqrt.rb
|
|
174
|
-
- lib/unitsml/transform.rb
|
|
175
161
|
- lib/unitsml/unit.rb
|
|
176
162
|
- lib/unitsml/unitsdb.rb
|
|
177
163
|
- lib/unitsml/unitsdb/database.rb
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unitsml
|
|
4
|
-
module IntermediateExpRules
|
|
5
|
-
include Parslet
|
|
6
|
-
|
|
7
|
-
# Rules for slashed number
|
|
8
|
-
rule(:slashed_number_int_exp) do
|
|
9
|
-
slashed_number | (opening_paren >> slashed_number_named_int_exp.as(:int_exp) >> closing_paren)
|
|
10
|
-
end
|
|
11
|
-
rule(:slashed_number_named_int_exp) do
|
|
12
|
-
(opening_paren.as(:open_paren) >> slashed_number_int_exp >> closing_paren.as(:close_paren)) |
|
|
13
|
-
slashed_number_int_exp
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Rules for prefixes_units
|
|
17
|
-
rule(:wrapper_prefixes_units_value) do
|
|
18
|
-
int_exp_prefixes_units | prefixes_units_int_exp
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
rule(:extended_prefixed_units) do
|
|
22
|
-
extender >> spaces? >> prefixes_units_int_exp.as(:sequence)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
rule(:int_exp_prefixes_units) do
|
|
26
|
-
opening_paren >> spaces? >> named_int_exp_prefixes_units.as(:int_exp) >> spaces? >> closing_paren
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
rule(:implicit_extended) do
|
|
30
|
-
(prefixes_units.as(:first_set) >> spaces.as(:extender) >> prefixes_units.as(:second_set)) |
|
|
31
|
-
(int_exp_prefixes_units.as(:first_int_exp_set) >> spaces? >> int_exp_prefixes_units.as(:second_int_exp_set)) |
|
|
32
|
-
(prefixes_units.as(:first_set) >> spaces? >> int_exp_prefixes_units.as(:second_int_exp_set)) |
|
|
33
|
-
(int_exp_prefixes_units.as(:first_int_exp_set) >> spaces? >> prefixes_units.as(:second_set))
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
rule(:prefixes_units_int_exp) do
|
|
37
|
-
(implicit_extended.as(:implicit_extended) >> spaces? >> prefixes_units_int_exp.as(:sequence).maybe) |
|
|
38
|
-
(implicit_extended.as(:implicit_extended) >> spaces? >> extender >> spaces? >> prefixes_units_int_exp.as(:sequence).maybe) |
|
|
39
|
-
(int_exp_prefixes_units >> spaces? >> extender >> spaces? >> prefixes_units_int_exp.as(:sequence).maybe) |
|
|
40
|
-
(prefixes_units >> spaces? >> extender >> spaces? >> prefixes_units_int_exp.as(:sequence).maybe) |
|
|
41
|
-
(int_exp_prefixes_units >> prefixes_units_int_exp.as(:sequence).maybe) |
|
|
42
|
-
(prefixes_units >> prefixes_units_int_exp.as(:sequence).maybe)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
rule(:prefixes_units_named_int_exp) do
|
|
46
|
-
opening_paren.as(:open_paren) >> spaces? >> wrapper_prefixes_units_value.as(:int_exp) >> spaces? >> closing_paren.as(:close_paren)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
rule(:named_int_exp_prefixes_units) do
|
|
50
|
-
(prefixes_units_named_int_exp.as(:int_exp) >> (prefixes_units_int_exp | extended_prefixed_units).maybe) |
|
|
51
|
-
prefixes_units_int_exp
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Rules for dimension_rules
|
|
55
|
-
rule(:dimension_rules_int_exp) do
|
|
56
|
-
(dimension_rules.as(:first_set) >> spaces.as(:extender) >> dimension_rules.as(:second_set) >> dimension_rules_int_exp.maybe) |
|
|
57
|
-
(dimension_rules.as(:first_set) >> spaces? >> int_exp_dimension_rules.as(:second_int_exp_set) >> dimension_rules_int_exp.maybe) |
|
|
58
|
-
(int_exp_dimension_rules.as(:first_int_exp_set) >> spaces? >> dimension_rules.as(:second_set) >> dimension_rules_int_exp.maybe) |
|
|
59
|
-
(int_exp_dimension_rules.as(:first_int_exp_set) >> spaces? >> int_exp_dimension_rules.as(:second_int_exp_set) >> dimension_rules_int_exp.maybe) |
|
|
60
|
-
int_exp_dimension_rules |
|
|
61
|
-
dimension_rules
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
rule(:int_exp_dimension_rules) do
|
|
65
|
-
opening_paren >> dimension_rules_named_exp.as(:int_exp) >> closing_paren >> extended_dimension_rules.maybe
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
rule(:extended_dimension_rules) do
|
|
69
|
-
spaces? >> extender >> spaces? >> dimension_rules_int_exp.as(:sequence)
|
|
70
|
-
end
|
|
71
|
-
rule(:dimension_rules_named_exp) do
|
|
72
|
-
((opening_paren.as(:open_paren) >> dimension_rules_int_exp.as(:int_exp) >> closing_paren.as(:close_paren)).as(:int_exp) >> spaces? >> (dimension_rules_int_exp | extended_dimension_rules).as(:sequence).maybe) |
|
|
73
|
-
dimension_rules_int_exp
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Rules for dimensions
|
|
77
|
-
rule(:sqrt_dimensions) do
|
|
78
|
-
sqrt >> opening_paren >> dimension_rules_int_exp.as(:sqrt) >> closing_paren
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Rules for sequence
|
|
82
|
-
rule(:sqrt_sequence) do
|
|
83
|
-
sqrt >> opening_paren >> prefixes_units_int_exp.as(:sqrt) >> closing_paren
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
data/lib/unitsml/parse.rb
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "parslet"
|
|
4
|
-
|
|
5
|
-
module Unitsml
|
|
6
|
-
class Parse < Parslet::Parser
|
|
7
|
-
include IntermediateExpRules
|
|
8
|
-
|
|
9
|
-
rule(:sqrt) { str("sqrt") }
|
|
10
|
-
rule(:power) { str("^") >> slashed_number_int_exp.as(:power_numerator) }
|
|
11
|
-
rule(:hyphen) { str("-") }
|
|
12
|
-
rule(:number) { hyphen.maybe >> match(/[0-9]/).repeat(1) }
|
|
13
|
-
rule(:spaces) { match(/\s/).repeat(1) }
|
|
14
|
-
rule(:spaces?) { spaces.maybe }
|
|
15
|
-
|
|
16
|
-
rule(:extender) { (forward_slashes | str("*")).as(:extender) }
|
|
17
|
-
rule(:sequence) do
|
|
18
|
-
(single_letter_prefixes >> units) | (double_letter_prefixes >> units) | units
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
rule(:opening_paren) { str("(") }
|
|
22
|
-
rule(:closing_paren) { str(")") }
|
|
23
|
-
rule(:unit_and_power) { units >> power.maybe }
|
|
24
|
-
rule(:slashed_number) do
|
|
25
|
-
(number >> (forward_slashes >> number).maybe).as(:integer)
|
|
26
|
-
end
|
|
27
|
-
rule(:forward_slashes) { str("//") | str("/") }
|
|
28
|
-
rule(:dimension_rules) do
|
|
29
|
-
(sqrt_dimensions | powered_dimensions) >> extended_dimension_rules.maybe
|
|
30
|
-
end
|
|
31
|
-
rule(:powered_dimensions) { dimensions >> power.maybe }
|
|
32
|
-
|
|
33
|
-
rule(:units) do
|
|
34
|
-
@@filtered_units ||= arr_to_expression(::Unitsml::Unitsdb.units.filtered,
|
|
35
|
-
"unit")
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
rule(:single_letter_prefixes) do
|
|
39
|
-
@@prefixes1 ||= arr_to_expression(::Unitsml::Unitsdb.prefixes_by_size(1),
|
|
40
|
-
"prefix")
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
rule(:double_letter_prefixes) do
|
|
44
|
-
@@prefixes2 ||= arr_to_expression(::Unitsml::Unitsdb.prefixes_by_size(2),
|
|
45
|
-
"prefix")
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
rule(:dimensions) do
|
|
49
|
-
@@dimensions ||= arr_to_expression(
|
|
50
|
-
::Unitsml::Unitsdb.dimensions.parsables.keys, "dimension"
|
|
51
|
-
)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
rule(:prefixes_units) do
|
|
55
|
-
(sqrt_sequence >> extended_prefixed_units.maybe) |
|
|
56
|
-
(str("1").as(:unit) >> extended_prefixed_units.maybe) |
|
|
57
|
-
(unit_and_power >> extended_prefixed_units) |
|
|
58
|
-
(unit_and_power >> (any.absent? | (extender | opening_paren | closing_paren | spaces).present?)) |
|
|
59
|
-
(double_letter_prefixes >> unit_and_power >> extended_prefixed_units) |
|
|
60
|
-
(double_letter_prefixes >> unit_and_power) |
|
|
61
|
-
(single_letter_prefixes >> unit_and_power >> extended_prefixed_units) |
|
|
62
|
-
(single_letter_prefixes >> unit_and_power)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
rule(:expression) do
|
|
66
|
-
prefixes_units_int_exp |
|
|
67
|
-
dimension_rules_int_exp |
|
|
68
|
-
(single_letter_prefixes >> hyphen) |
|
|
69
|
-
(double_letter_prefixes >> hyphen)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
root :expression
|
|
73
|
-
|
|
74
|
-
def arr_to_expression(arr, file_name)
|
|
75
|
-
array = arr&.flatten&.compact&.sort_by(&:length)&.reverse
|
|
76
|
-
array&.reduce do |expression, expr_string|
|
|
77
|
-
expression = str(expression).as(file_name.to_sym) if expression.is_a?(String)
|
|
78
|
-
expression | str(expr_string).as(file_name.to_sym)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|