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
- .class_name(klass) ⇒ Object
- .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
- .display_exp(unit) ⇒ Object
- .float_to_display(float) ⇒ Object
- .gather_units(units) ⇒ Object
- .html_entity_to_unicode(string) ⇒ Object
- .postprocess_normtext(units) ⇒ 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(units, text, name) ⇒ Object
- .units2dimensions(units) ⇒ Object
- .unitsymbols(formula, options) ⇒ Object
- .unitsystem(units) ⇒ Object
Class Method Details
.class_name(klass) ⇒ Object
311 312 313 |
# File 'lib/unitsml/utility.rb', line 311 def class_name(klass) klass.name.split("::").last end |
.combine_prefixes(p1, p2) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/unitsml/utility.rb', line 129 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
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/unitsml/utility.rb', line 87 def decompose_unit(u) if u&.unit_name == "g" || 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.nil? && !k.prefix.empty? combine_prefixes(prefix_object(k.prefix), u.prefix) else u.prefix end unit_name = Unitsdb.units.find_by_id(k.id).unit_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
83 84 85 |
# File 'lib/unitsml/utility.rb', line 83 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 |
# 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
195 196 197 198 199 200 201 202 203 |
# File 'lib/unitsml/utility.rb', line 195 def dimension(norm_text) dim_url = unit_instance(norm_text)&.dimension_url return unless dim_url dim_id = dim_url.sub("#", '') 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
205 206 207 208 209 210 211 212 |
# File 'lib/unitsml/utility.rb', line 205 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
269 270 271 272 273 274 275 |
# File 'lib/unitsml/utility.rb', line 269 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
218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/unitsml/utility.rb', line 218 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_numerator, } end end |
.display_exp(unit) ⇒ Object
170 171 172 |
# File 'lib/unitsml/utility.rb', line 170 def display_exp(unit) unit.power_numerator && unit.power_numerator != "1" ? "^#{unit.power_numerator}" : "" end |
.float_to_display(float) ⇒ Object
214 215 216 |
# File 'lib/unitsml/utility.rb', line 214 def float_to_display(float) float.to_f.round(1).to_s.sub(/\.0$/, "") end |
.gather_units(units) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/unitsml/utility.rb', line 108 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
302 303 304 305 |
# File 'lib/unitsml/utility.rb', line 302 def html_entity_to_unicode(string) entities = HTMLEntities.new entities.decode(string) end |
.postprocess_normtext(units) ⇒ Object
166 167 168 |
# File 'lib/unitsml/utility.rb', line 166 def postprocess_normtext(units) units.map { |u| "#{u.prefix_name}#{u.unit_name}#{display_exp(u)}" }.join("*") end |
.prefix_object(prefix) ⇒ Object
122 123 124 125 126 127 |
# File 'lib/unitsml/utility.rb', line 122 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
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/unitsml/utility.rb', line 233 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
277 278 279 280 281 282 283 284 285 286 |
# File 'lib/unitsml/utility.rb', line 277 def quantity(normtext, quantity) unit = unit_instance(normtext) return unless unit && unit.quantity_reference.size == 1 || quantity_instance(quantity) id = (quantity || unit.quantity_reference&.first&.url).sub('#', '') dim_url = unit.dimension_url attributes = { id: id, name: quantity_name(id), dimension_url: dim_url } Model::Quantity.new(attributes).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
288 289 290 291 292 |
# File 'lib/unitsml/utility.rb', line 288 def quantity_name(id) quantity_instance(id)&.quantity_name&.map do |content| Model::Quantities::Name.new(content: content) end end |
.rootunits(units) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/unitsml/utility.rb', line 249 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
294 295 296 297 298 299 300 |
# File 'lib/unitsml/utility.rb', line 294 def string_to_html_entity(string) entities = HTMLEntities.new entities.encode( string.frozen? ? string : string.force_encoding('UTF-8'), :hexadecimal, ) end |
.underscore(str) ⇒ Object
307 308 309 |
# File 'lib/unitsml/utility.rb', line 307 def underscore(str) str.gsub(/([a-z])([A-Z])/, '\1_\2').downcase end |
.unit(units, formula, dims, norm_text, name, options) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/unitsml/utility.rb', line 143 def unit(units, formula, dims, norm_text, name, ) attributes = { id: unit_id(norm_text), system: unitsystem(units), name: unitname(units, 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
262 263 264 265 266 267 |
# File 'lib/unitsml/utility.rb', line 262 def unit_id(text) norm_text = text text = text&.gsub(/[()]/, "") unit = unit_instance(norm_text) "U_#{unit ? unit.id&.gsub(/'/, '_') : norm_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(units, text, name) ⇒ Object
160 161 162 163 164 |
# File 'lib/unitsml/utility.rb', line 160 def unitname(units, text, name) Model::Units::Name.new( name: unit_instance(text)&.unit_name&.first || text ) 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
174 175 176 177 178 |
# File 'lib/unitsml/utility.rb', line 174 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
180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/unitsml/utility.rb', line 180 def unitsystem(units) ret = [] if units.any? { |u| u.system_name != "SI" } ret << Model::Units::System.new(name: "not_SI", type: "not_SI") end if units.any? { |u| u.system_name == "SI" } if units.size == 1 base = units[0].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 |