Module: Unitsml::Utility
- Defined in:
- lib/unitsml/utility.rb
Constant Summary collapse
- U2D =
Unit to dimension
{ "m" => { dimension: "Length", order: 1, symbol: "L" }, "g" => { dimension: "Mass", order: 2, symbol: "M" }, "kg" => { dimension: "Mass", order: 2, symbol: "M" }, "s" => { dimension: "Time", order: 3, symbol: "T" }, "A" => { dimension: "ElectricCurrent", order: 4, symbol: "I" }, "K" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" }, "degK" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" }, "mol" => { dimension: "AmountOfSubstance", order: 6, symbol: "N" }, "cd" => { dimension: "LuminousIntensity", order: 7, symbol: "J" }, "deg" => { dimension: "PlaneAngle", order: 8, symbol: "phi" }, }.freeze
- Dim2D =
Dimesion for dim_(dimesion) input
{ "dim_L" => U2D["m"], "dim_M" => U2D["g"], "dim_T" => U2D["s"], "dim_I" => U2D["A"], "dim_Theta" => U2D["K"], "dim_N" => U2D["mol"], "dim_J" => U2D["cd"], "dim_phi" => U2D["deg"], }.freeze
- DIMS_VECTOR =
%w[ ThermodynamicTemperature AmountOfSubstance LuminousIntensity ElectricCurrent PlaneAngle Length Mass Time ].freeze
Class Method Summary collapse
- .combine_prefixes(p1, p2) ⇒ Object
- .decompose_unit(u) ⇒ Object
- .decompose_units_list(units) ⇒ Object
- .dim_id(dims) ⇒ Object
- .dimension(norm_text) ⇒ Object
- .dimension1(dim, dims_hash) ⇒ Object
- .dimension_components(dims) ⇒ Object
- .dimid2dimensions(normtext) ⇒ Object
- .float_to_display(float) ⇒ Object
- .gather_units(units) ⇒ Object
- .html_entity_to_unicode(string) ⇒ Object
- .prefix_object(prefix) ⇒ Object
- .prefixes(units, options) ⇒ Object
- .quantity(normtext, quantity) ⇒ Object
- .quantity_instance(id) ⇒ Object
- .quantity_name(id) ⇒ Object
- .rootunits(units) ⇒ Object
- .string_to_html_entity(string) ⇒ Object
- .underscore(str) ⇒ Object
- .unit(units, formula, dims, norm_text, name, options) ⇒ Object
- .unit_id(text) ⇒ Object
- .unit_instance(unit) ⇒ Object
- .unitname(text, name) ⇒ Object
- .units2dimensions(units) ⇒ Object
- .unitsymbols(formula, options) ⇒ Object
- .unitsystem(units) ⇒ Object
Class Method Details
.combine_prefixes(p1, p2) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/unitsml/utility.rb', line 130 def combine_prefixes(p1, p2) return nil if p1.nil? && p2.nil? return p1.symbolid if p2.nil? return p2.symbolid if p1.nil? return "unknown" if p1.base != p2.base Unitsdb.prefixes_array.each do |prefix_name| p = prefix_object(prefix_name) return p if p.base == p1.base && p.power == p1.power + p2.power end "unknown" end |
.decompose_unit(u) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/unitsml/utility.rb', line 88 def decompose_unit(u) if u&.unit_name == "g" || Lutaml::Model::Utils.snake_case(u.system_type) == "si_base" { unit: u, prefix: u&.prefix } elsif u.si_derived_bases.nil? || u.si_derived_bases.empty? { unit: Unit.new("unknown") } else u.si_derived_bases.each_with_object([]) do |k, object| prefix = if !k.prefix_reference.nil? combine_prefixes(prefix_object(k.prefix_reference), u.prefix) else u.prefix end unit_name = Unitsdb.units.find_by_id(k.unit_reference.id).symbols.first.id exponent = (k.power&.to_i || 1) * (u.power_numerator&.to_f || 1) object << { prefix: prefix, unit: Unit.new(unit_name, exponent, prefix: prefix), } end end end |
.decompose_units_list(units) ⇒ Object
84 85 86 |
# File 'lib/unitsml/utility.rb', line 84 def decompose_units_list(units) gather_units(units.map { |u| decompose_unit(u) }.flatten) end |
.dim_id(dims) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/unitsml/utility.rb', line 71 def dim_id(dims) return nil if dims.nil? || dims.empty? dim_hash = dims.each_with_object({}) { |h, m| m[h[:dimension]] = h } dims_vector = DIMS_VECTOR.map { |h| dim_hash.dig(h, :exponent) }.join(":") id = Unitsdb.dimensions.find_by_vector(dims_vector)&.id and return id.to_s "D_" + dims.map do |d| (U2D.dig(d[:unit], :symbol) || Dim2D.dig(d[:id], :symbol)) + (d[:exponent] == 1 ? "" : float_to_display(d[:exponent])) end.join("") end |
.dimension(norm_text) ⇒ Object
190 191 192 193 194 195 196 197 |
# File 'lib/unitsml/utility.rb', line 190 def dimension(norm_text) dim_id = unit_instance(norm_text)&.dimension_url return unless dim_id dim_attrs = { id: dim_id } dimid2dimensions(dim_id)&.compact&.each { |u| dimension1(u, dim_attrs) } Model::Dimension.new(dim_attrs).to_xml end |
.dimension1(dim, dims_hash) ⇒ Object
199 200 201 202 203 204 205 206 |
# File 'lib/unitsml/utility.rb', line 199 def dimension1(dim, dims_hash) dim_name = dim[:dimension] dim_klass = Model::DimensionQuantities.const_get(dim_name) dims_hash[underscore(dim_name).to_sym] = dim_klass.new( symbol: dim[:symbol], power_numerator: float_to_display(dim[:exponent]) ) end |
.dimension_components(dims) ⇒ Object
263 264 265 266 267 268 269 |
# File 'lib/unitsml/utility.rb', line 263 def dimension_components(dims) return if dims.nil? || dims.empty? dim_attrs = { id: dim_id(dims) } dims.map { |u| dimension1(u, dim_attrs) } Model::Dimension.new(dim_attrs).to_xml end |
.dimid2dimensions(normtext) ⇒ Object
212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/unitsml/utility.rb', line 212 def dimid2dimensions(normtext) dims = Unitsdb.dimensions.find_by_id(normtext) dims&.processed_keys&.map do |processed_key| humanized = processed_key.split("_").map(&:capitalize).join next unless DIMS_VECTOR.include?(humanized) dim_quantity = dims.public_send(processed_key) { dimension: humanized, symbol: dim_quantity.symbol, exponent: dim_quantity.power, } end end |
.float_to_display(float) ⇒ Object
208 209 210 |
# File 'lib/unitsml/utility.rb', line 208 def float_to_display(float) float.to_f.round(1).to_s.sub(/\.0$/, "") end |
.gather_units(units) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/unitsml/utility.rb', line 109 def gather_units(units) units.sort_by { |a| a[:unit]&.unit_name }.each_with_object([]) do |k, m| if m.empty? || m[-1][:unit]&.unit_name != k[:unit]&.unit_name m << k else m[-1][:unit]&.power_numerator = (k[:unit]&.power_numerator&.to_f || 1) + (m[-1][:unit]&.power_numerator&.to_f || 1) m[-1] = { prefix: combine_prefixes(prefix_object(m[-1][:prefix]), prefix_object(k[:prefix])), unit: m[-1][:unit], } end end end |
.html_entity_to_unicode(string) ⇒ Object
299 300 301 |
# File 'lib/unitsml/utility.rb', line 299 def html_entity_to_unicode(string) HTMLEntities.new.decode(string) end |
.prefix_object(prefix) ⇒ Object
123 124 125 126 127 128 |
# File 'lib/unitsml/utility.rb', line 123 def prefix_object(prefix) return prefix unless prefix.is_a?(String) return nil unless Unitsdb.prefixes_array.any?(prefix) Prefix.new(prefix) end |
.prefixes(units, options) ⇒ Object
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/unitsml/utility.rb', line 227 def prefixes(units, ) uniq_prefixes = units.map { |unit| unit.prefix }.compact.uniq { |d| d.prefix_name } uniq_prefixes.map do |prefix| prefix_attrs = { prefix_base: prefix&.base, prefix_power: prefix&.power, id: prefix&.id } type_and_methods = { ASCII: :to_asciimath, unicode: :to_unicode, LaTeX: :to_latex, HTML: :to_html } prefix_attrs[:name] = Model::Prefixes::Name.new(content: prefix&.name) prefix_attrs[:symbol] = type_and_methods.map do |type, method_name| Model::Prefixes::Symbol.new( type: type, content: prefix&.public_send(method_name, ), ) end Model::Prefix.new(prefix_attrs).to_xml.gsub("&", "&") end.join("\n") end |
.quantity(normtext, quantity) ⇒ Object
271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/unitsml/utility.rb', line 271 def quantity(normtext, quantity) unit = unit_instance(normtext) return unless unit && unit.quantity_references.size == 1 || quantity_instance(quantity) id = (quantity || unit.quantity_references&.first&.id) Model::Quantity.new( id: id, name: quantity_name(id), dimension_url: "##{unit.dimension_url}", ).to_xml end |
.quantity_instance(id) ⇒ Object
52 53 54 |
# File 'lib/unitsml/utility.rb', line 52 def quantity_instance(id) Unitsdb.quantities.find_by_id(id) end |
.quantity_name(id) ⇒ Object
284 285 286 287 288 289 290 |
# File 'lib/unitsml/utility.rb', line 284 def quantity_name(id) quantity_instance(id)&.names&.filter_map do |name| next unless name.lang == "en" Model::Quantities::Name.new(content: name.value) end end |
.rootunits(units) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/unitsml/utility.rb', line 243 def rootunits(units) return if units.size == 1 && !units[0].prefix enum_root_units = units.map do |unit| attributes = { unit: unit.enumerated_name } attributes[:prefix] = unit.prefix_name if unit.prefix unit.power_numerator && unit.power_numerator != "1" and attributes[:power_numerator] = unit.power_numerator Model::Units::EnumeratedRootUnit.new(attributes) end Model::Units::RootUnits.new(enumerated_root_unit: enum_root_units) end |
.string_to_html_entity(string) ⇒ Object
292 293 294 295 296 297 |
# File 'lib/unitsml/utility.rb', line 292 def string_to_html_entity(string) HTMLEntities.new.encode( string.frozen? ? string : string.force_encoding('UTF-8'), :hexadecimal, ) end |
.underscore(str) ⇒ Object
303 304 305 |
# File 'lib/unitsml/utility.rb', line 303 def underscore(str) str.gsub(/([a-z])([A-Z])/, '\1_\2').downcase end |
.unit(units, formula, dims, norm_text, name, options) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/unitsml/utility.rb', line 144 def unit(units, formula, dims, norm_text, name, ) attributes = { id: unit_id(norm_text), system: unitsystem(units), name: unitname(norm_text, name), symbol: unitsymbols(formula, ), root_units: rootunits(units), } attributes[:dimension_url] = "##{dim_id(dims)}" if dims Model::Unit.new(attributes).to_xml .gsub("<", "<") .gsub(">", ">") .gsub("&", "&") .gsub(/−/, "−") .gsub(/⋅/, "⋅") end |
.unit_id(text) ⇒ Object
256 257 258 259 260 261 |
# File 'lib/unitsml/utility.rb', line 256 def unit_id(text) text = text&.gsub(/[()]/, "") unit = unit_instance(text) "U_#{unit ? unit.nist_id&.gsub(/'/, '_') : text&.gsub(/\*/, '.')&.gsub(/\^/, '')}" end |
.unit_instance(unit) ⇒ Object
48 49 50 |
# File 'lib/unitsml/utility.rb', line 48 def unit_instance(unit) Unitsdb.units.find_by_symbol_id(unit) end |
.unitname(text, name) ⇒ Object
161 162 163 164 |
# File 'lib/unitsml/utility.rb', line 161 def unitname(text, name) name ||= unit_instance(text)&.en_name || text Model::Units::Name.new(name: name) end |
.units2dimensions(units) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/unitsml/utility.rb', line 56 def units2dimensions(units) norm = decompose_units_list(units) return if norm.any? { |u| u.nil? || u[:unit].unit_name == "unknown" || u[:prefix] == "unknown" } norm.map do |u| unit_name = u[:unit].unit_name { dimension: U2D[unit_name][:dimension], unit: unit_name, exponent: u[:unit].power_numerator || 1, symbol: U2D[unit_name][:symbol], } end.sort { |a, b| U2D[a[:unit]][:order] <=> U2D[b[:unit]][:order] } end |
.unitsymbols(formula, options) ⇒ Object
166 167 168 169 170 171 172 173 |
# File 'lib/unitsml/utility.rb', line 166 def unitsymbols(formula, ) %w[HTML MathMl].map do |lang| Model::Units::Symbol.new( type: lang, content: formula.public_send(:"to_#{lang.downcase}", ), ) end end |
.unitsystem(units) ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/unitsml/utility.rb', line 175 def unitsystem(units) ret = [] if units.any? { |u| !u.si_system_type? } ret << Model::Units::System.new(name: "not_SI", type: "not_SI") end if units.any?(&:si_system_type?) if units.size == 1 base = units[0].downcase_system_type == "si_base" base = true if units[0].unit_name == "g" && units[0]&.prefix_name == "k" end ret << Model::Units::System.new(name: "SI", type: (base ? 'SI_base' : 'SI_derived')) end ret end |