diff --git a/Gemfile b/Gemfile index c048116..2885b2b 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem "byebug" gem "equivalent-xml" gem "oga" gem "ox" -gem "plurimath" +gem "plurimath", github: "plurimath/plurimath", branch: "update/mathml_symbol_transformation" gem "pry" gem "rake" gem "rspec" diff --git a/lib/unitsml.rb b/lib/unitsml.rb index b8bb4b1..e82dd2d 100644 --- a/lib/unitsml.rb +++ b/lib/unitsml.rb @@ -14,10 +14,25 @@ def parse(string) def register @register ||= Lutaml::Model::GlobalRegister.lookup(REGISTER_ID) end + + def register_model(klass, id:) + register.register_model(klass, id: id) + end + + def get_class_from_register(class_name) + register.get_class(class_name) + end + + def register_type_substitution(from:, to:) + register.register_global_type_substitution( + from_type: from, + to_type: to, + ) + end end Lutaml::Model::GlobalRegister.register( - Lutaml::Model::Register.new(Unitsml::REGISTER_ID) + Lutaml::Model::Register.new(Unitsml::REGISTER_ID), ) require "unitsdb" @@ -25,6 +40,8 @@ def register require "unitsml/sqrt" require "unitsml/unit" require "unitsml/parse" +require "unitsml/fenced_numeric" +require "unitsml/number" require "unitsml/parser" require "unitsml/prefix" require "unitsml/fenced" @@ -51,11 +68,7 @@ def register ::Unitsdb::PrefixReference => Unitsml::Unitsdb::PrefixReference, ::Unitsdb::DimensionDetails => Unitsml::Unitsdb::DimensionQuantity, }.each do |key, value| - Unitsml.register - .register_global_type_substitution( - from_type: key, - to_type: value, - ) + Unitsml.register_type_substitution(from: key, to: value) end Lutaml::Model::Config.xml_adapter_type = RUBY_ENGINE == "opal" ? :oga : :ox diff --git a/lib/unitsml/dimension.rb b/lib/unitsml/dimension.rb index 093c309..e471405 100644 --- a/lib/unitsml/dimension.rb +++ b/lib/unitsml/dimension.rb @@ -16,56 +16,52 @@ def ==(object) end def dim_instance - @dim ||= Unitsdb.dimensions.find_parsables_by_id(dimension_name) + @dim_instance ||= Unitsdb.dimensions.find_parsables_by_id(dimension_name) end def dim_symbols - dim_instance.send(@dim.processed_keys.last).symbols.first + dim_instance.send(dim_instance.processed_keys.last).symbols.first end - def to_mathml(_) - # MathML key's value in unitsdb/dimensions.yaml file includes mi tags only. + def to_mathml(options) + # MathML key's value in unitsdb/dimensions.yaml + # file includes mi tags only. value = ::Mml::Mi.from_xml(dim_symbols.mathml) - method_name = power_numerator ? :msup : :mi - if power_numerator - value = ::Mml::Msup.new( - mrow_value: [ - ::Mml::Mrow.new(mi_value: [value]), - ::Mml::Mrow.new( - mn_value: [::Mml::Mn.new(value: power_numerator)], - ), - ] - ) - end + method_name = if power_numerator + value = msup_tag(value, options) + :msup + else + :mi + end { method_name: method_name, value: value } end - def to_latex(_) - power_numerator_generic_code(:latex) + def to_latex(options) + power_numerator_generic_code(:latex, options) end - def to_asciimath(_) - power_numerator_generic_code(:ascii) + def to_asciimath(options) + power_numerator_generic_code(:ascii, options) end - def to_unicode(_) - power_numerator_generic_code(:unicode) + def to_unicode(options) + power_numerator_generic_code(:unicode, options) end - def to_html(_) + def to_html(options) value = dim_symbols.html - value = "#{value}#{power_numerator}" if power_numerator + value = "#{value}#{html_numerator_conversion(options)}" if power_numerator value end def generate_id - "#{dimension_name.split('_').last}#{power_numerator}" + "#{dimension_name.split('_').last}#{power_numerator&.raw_value}" end def to_xml(_) attributes = { symbol: dim_instance.processed_symbol, - power_numerator: power_numerator || 1, + power_numerator: power_numerator&.raw_value || 1, } Model::DimensionQuantities.const_get(modelize(element_name)).new(attributes) end @@ -80,15 +76,33 @@ def modelize(value) private - def power_numerator_generic_code(method_name) + def html_numerator_conversion(options) + "#{power_numerator.to_html(options)}" + end + + def power_numerator_generic_code(method_name, options) value = dim_symbols.public_send(method_name) return value unless power_numerator - "#{value}^#{power_numerator}" + method_name = :asciimath if method_name == :ascii + "#{value}^#{power_numerator&.public_send(:"to_#{method_name}", options)}" end def element_name dim_instance.processed_keys.first end + + def msup_tag(value, options) + mathml = power_numerator.to_mathml(options) + msup = ::Mml::Msup.new( + mrow_value: [::Mml::Mrow.new(mi_value: [value])], + ) + [mathml].flatten.each do |record| + record_values = msup.public_send("#{record[:method_name]}_value") || [] + record_values += [record[:value]] + msup.public_send("#{record[:method_name]}_value=", record_values) + end + msup + end end end diff --git a/lib/unitsml/extender.rb b/lib/unitsml/extender.rb index c5fa575..a9f053e 100644 --- a/lib/unitsml/extender.rb +++ b/lib/unitsml/extender.rb @@ -35,8 +35,7 @@ def to_html(options) end def to_unicode(options) - extender = options[:multiplier] || - symbol == "*" ? "·" : symbol + extender = options[:multiplier] || unicode_extender multiplier(extender) end @@ -45,16 +44,22 @@ def to_unicode(options) def multiplier(extender, unicode: false, html: false) case extender when :space - if html - " " - else - unicode ? "⁢" : " " - end + space_extender(html, unicode) when :nospace unicode ? "⁢" : "" else unicode ? Utility.string_to_html_entity(extender) : extender end end + + def space_extender(html, unicode) + return " " if html + + unicode ? "⁢" : " " + end + + def unicode_extender + symbol == "*" ? "·" : symbol + end end end diff --git a/lib/unitsml/fenced.rb b/lib/unitsml/fenced.rb index dc1dab8..15a2052 100644 --- a/lib/unitsml/fenced.rb +++ b/lib/unitsml/fenced.rb @@ -1,5 +1,7 @@ module Unitsml class Fenced + include FencedNumeric + attr_reader :open_paren, :value, :close_paren def initialize(open_paren, value, close_paren) @@ -36,6 +38,22 @@ def to_mathml(options = {}) { method_name: :mrow, value: fenced } end + def negative? + value.negative? + end + + def update_negative_sign + value.update_negative_sign + end + + def float_to_display + value.float_to_display + end + + def raw_value + value.raw_value + end + def to_html(options = {}) fenced_conversion_for(lang: :html, options: options) end diff --git a/lib/unitsml/fenced_numeric.rb b/lib/unitsml/fenced_numeric.rb new file mode 100644 index 0000000..fdf1f3e --- /dev/null +++ b/lib/unitsml/fenced_numeric.rb @@ -0,0 +1,11 @@ +module Unitsml + module FencedNumeric + def to_i + value.to_i + end + + def to_f + value.to_f + end + end +end diff --git a/lib/unitsml/formula.rb b/lib/unitsml/formula.rb index 4ae16d5..3388688 100644 --- a/lib/unitsml/formula.rb +++ b/lib/unitsml/formula.rb @@ -92,7 +92,7 @@ def extract_dimensions(formula) elsif term.is_a?(Sqrt) if term.value.is_a?(Dimension) sqrt_term = term.value.dup - sqrt_term.power_numerator = "0.5" + sqrt_term.power_numerator = Number.new("0.5") dimensions << sqrt_term elsif term.value.is_a?(Fenced) dimensions.concat(Array(term.value.dimensions_extraction)) @@ -149,7 +149,7 @@ def dimensions(dims, options) end def sort_dims(values) - dims_hash = Utility::Dim2D + dims_hash = Utility::DIM2D values.sort do |first, second| dims_hash.dig(first.dimension_name, :order) <=> dims_hash.dig(second.dimension_name, :order) end diff --git a/lib/unitsml/intermediate_exp_rules.rb b/lib/unitsml/intermediate_exp_rules.rb index d8bbc95..00c1d85 100644 --- a/lib/unitsml/intermediate_exp_rules.rb +++ b/lib/unitsml/intermediate_exp_rules.rb @@ -3,7 +3,11 @@ module IntermediateExpRules include Parslet # Rules for slashed number - rule(:slashed_number_int_exp) { slashed_number | (opening_paren >> slashed_number >> closing_paren) } + rule(:slashed_number_int_exp) { slashed_number | (opening_paren >> slashed_number_named_int_exp.as(:int_exp) >> closing_paren) } + rule(:slashed_number_named_int_exp) do + (opening_paren.as(:open_paren) >> slashed_number_int_exp >> closing_paren.as(:close_paren)) | + slashed_number_int_exp + end # Rules for prefixes_units rule(:wrapper_prefixes_units_value) { int_exp_prefixes_units | prefixes_units_int_exp } diff --git a/lib/unitsml/number.rb b/lib/unitsml/number.rb new file mode 100644 index 0000000..6a283ee --- /dev/null +++ b/lib/unitsml/number.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +module Unitsml + class Number + include FencedNumeric + + attr_accessor :value + alias raw_value value + + def initialize(value) + @value = value + end + + def ==(object) + self.class == object.class && + value == object&.value + end + + def to_mathml(_options) + matched_value = value&.match(/-?(.+)/) + mn_value = matched_value ? matched_value[1] : value + mn_tag = ::Mml::Mn.new(value: mn_value) + value.start_with?("-") ? mrow_hash(mn_tag) : mn_hash(mn_tag) + end + + def to_html(_options) + value.sub("-", "−") + end + + def to_latex(_options) + value + end + + def to_asciimath(_options) + value + end + + def to_unicode(_options) + value + end + + def negative? + value.start_with?("-") + end + + def update_negative_sign + if negative? + self.value = value.delete_prefix("-") + else + self.value = ["-", value].join + end + end + + def float_to_display + return "" if value.nil? + + value.to_f.round(1).to_s.sub(/\.0$/, "") + end + + private + + def mrow_hash(mn_tag) + { + method_name: :mrow, + value: ::Mml::Mrow.new( + mo_value: [::Mml::Mo.new(value: "−")], + mn_value: [mn_tag], + ), + } + end + + def mn_hash(mn_tag) + { + method_name: :mn, + value: mn_tag, + } + end + end +end diff --git a/lib/unitsml/parse.rb b/lib/unitsml/parse.rb index fce3131..cecd88a 100644 --- a/lib/unitsml/parse.rb +++ b/lib/unitsml/parse.rb @@ -8,7 +8,7 @@ class Parse < Parslet::Parser include IntermediateExpRules rule(:sqrt) { str("sqrt") } - rule(:power) { str("^") >> slashed_number_int_exp } + rule(:power) { str("^") >> slashed_number_int_exp.as(:power_numerator) } rule(:hyphen) { str("-") } rule(:number) { hyphen.maybe >> match(/[0-9]/).repeat(1) } rule(:spaces) { match(/\s/).repeat(1) } diff --git a/lib/unitsml/parser.rb b/lib/unitsml/parser.rb index 039f5e6..f7fb8a6 100644 --- a/lib/unitsml/parser.rb +++ b/lib/unitsml/parser.rb @@ -33,7 +33,7 @@ def update_units_exponents(array, inverse, sqrt = false) if object.is_a?(Sqrt) object = object.value if object.respond_to?(:power_numerator) - object.power_numerator = "0.5" + object.power_numerator = Number.new("0.5") else update_units_exponents([object], inverse, true) end @@ -41,12 +41,11 @@ def update_units_exponents(array, inverse, sqrt = false) case object when Unit - next object.power_numerator = "0.5" if sqrt + next object.power_numerator = Number.new("0.5") if sqrt next unless inverse - exponent = inverse ? "-#{object&.power_numerator || '1'}" : object.power_numerator - object.power_numerator = exponent&.sub(/^--+/, "") - when Dimension then object.power_numerator = "0.5" if sqrt + inverse ? object.inverse_power_numerator : object.power_numerator + when Dimension then object.power_numerator = Number.new("0.5") if sqrt when Extender then inverse = !inverse if ["/", "//"].any?(object.symbol) when Formula then update_units_exponents(object.value, inverse) when Fenced then update_units_exponents([object.value], inverse, sqrt) diff --git a/lib/unitsml/transform.rb b/lib/unitsml/transform.rb index c6c900f..d51881e 100644 --- a/lib/unitsml/transform.rb +++ b/lib/unitsml/transform.rb @@ -7,6 +7,7 @@ class Transform < Parslet::Transform rule(unit: simple(:unit)) { Unit.new(unit.to_s) } rule(dimension: simple(:dimension)) { Dimension.new(dimension.to_s) } rule(prefix: simple(:prefix)) { Prefix.new(prefix.to_s) } + rule(integer: simple(:integer)) { Number.new(integer.to_s) } rule(int_exp: simple(:int_exp)) { int_exp } rule(implicit_extended: simple(:implicit_extended)) { implicit_extended } @@ -54,19 +55,19 @@ class Transform < Parslet::Transform end rule(unit: simple(:unit), - integer: simple(:integer)) do - Unit.new(unit.to_s, integer) + power_numerator: simple(:power_numerator)) do + Unit.new(unit.to_s, power_numerator) end rule(dimension: simple(:dimension), - integer: simple(:integer)) do - Dimension.new(dimension.to_s, integer) + power_numerator: simple(:power_numerator)) do + Dimension.new(dimension.to_s, power_numerator) end rule(prefix: simple(:prefix), unit: simple(:unit), - integer: simple(:integer)) do - Unit.new(unit.to_s, integer.to_s, prefix: Prefix.new(prefix.to_s)) + power_numerator: simple(:power_numerator)) do + Unit.new(unit.to_s, power_numerator, prefix: Prefix.new(prefix.to_s)) end rule(first_set: simple(:first_set), @@ -139,13 +140,23 @@ class Transform < Parslet::Transform ) end + rule(open_paren: simple(:open_paren), + integer: simple(:integer), + close_paren: simple(:close_paren)) do + Fenced.new( + open_paren.to_s, + Number.new(integer.to_s), + close_paren.to_s, + ) + end + rule(unit: simple(:unit), - integer: simple(:int), + power_numerator: simple(:power_numerator), extender: simple(:ext), sequence: simple(:sequence)) do Formula.new( [ - Unit.new(unit.to_s, int.to_s), + Unit.new(unit.to_s, power_numerator), Extender.new(ext.to_s), sequence, ], @@ -153,12 +164,12 @@ class Transform < Parslet::Transform end rule(dimension: simple(:dimension), - integer: simple(:int), + power_numerator: simple(:power_numerator), extender: simple(:ext), sequence: simple(:sequence)) do Formula.new( [ - Dimension.new(dimension.to_s, int.to_s), + Dimension.new(dimension.to_s, power_numerator), Extender.new(ext.to_s), sequence, ], @@ -180,12 +191,12 @@ class Transform < Parslet::Transform rule(prefix: simple(:prefix), unit: simple(:unit), - integer: simple(:integer), + power_numerator: simple(:power_numerator), extender: simple(:ext), sequence: simple(:sequence)) do Formula.new( [ - Unit.new(unit.to_s, integer.to_s, prefix: Prefix.new(prefix.to_s)), + Unit.new(unit.to_s, power_numerator, prefix: Prefix.new(prefix.to_s)), Extender.new(ext.to_s), sequence, ], diff --git a/lib/unitsml/unit.rb b/lib/unitsml/unit.rb index 93d8785..2f47a9d 100644 --- a/lib/unitsml/unit.rb +++ b/lib/unitsml/unit.rb @@ -25,22 +25,12 @@ def unit_instance Unitsdb.units.find_by_name(unit_name) end - def unit_symbols - unit_instance.symbols.find { |symbol| symbol.id == unit_name } + def unknown_name? + unit_name == Utility::UNKNOWN end - def numerator_value(mathml = true) - integer = power_numerator.to_s - unless integer.match?(/-/) - return mathml ? { mn_value: [::Mml::Mn.from_xml("#{integer}")] } : integer - end - - return integer.sub(/(-)(.+)/, '−\2') unless mathml - - integer = integer.sub(/(-)(.+)/, '\2') - integer = ::Mml::Mn.from_xml(integer) - mo_tag = ::Mml::Mo.new(value: "−") - { mo_value: [mo_tag], mn_value: [integer] } + def unit_symbols + unit_instance.symbols.find { |symbol| symbol.id == unit_name } end def to_mathml(options) @@ -49,11 +39,9 @@ def to_mathml(options) value = ::Mml.const_get(tag_name.capitalize).from_xml(value) value.value = "#{prefix.to_mathml(options)}#{value.value}" if prefix if power_numerator - value = ::Mml::Msup.new( - mrow_value: [ - ::Mml::Mrow.new("#{tag_name}_value": Array(value)), - ::Mml::Mrow.new(numerator_value), - ] + value = msup_tag( + { method_name: tag_name, value: value }, + options, ) tag_name = :msup end @@ -62,14 +50,14 @@ def to_mathml(options) def to_latex(options) value = unit_symbols&.latex - value = "#{value}^#{power_numerator}" if power_numerator + value = "#{value}^#{power_numerator.to_latex(options)}" if power_numerator value = "#{prefix.to_latex(options)}#{value}" if prefix value end def to_asciimath(options) value = unit_symbols&.ascii - value = "#{value}^#{power_numerator}" if power_numerator + value = "#{value}^#{power_numerator.to_asciimath(options)}" if power_numerator value = "#{prefix.to_asciimath(options)}#{value}" if prefix value end @@ -77,7 +65,7 @@ def to_asciimath(options) def to_html(options) value = unit_symbols&.html if power_numerator - value = "#{value}#{numerator_value(false)}" + value = "#{value}#{power_numerator.to_html(options)}" end value = "#{prefix.to_html(options)}#{value}" if prefix value @@ -85,7 +73,7 @@ def to_html(options) def to_unicode(options) value = unit_symbols&.unicode - value = "#{value}^#{power_numerator}" if power_numerator + value = "#{value}^#{power_numerator.to_unicode(options)}" if power_numerator value = "#{prefix.to_unicode(options)}#{value}" if prefix value end @@ -118,16 +106,38 @@ def downcase_system_type Lutaml::Model::Utils.snake_case(system_type) end + def inverse_power_numerator + if power_numerator + power_numerator.update_negative_sign + else + @power_numerator = Number.new("-1") + end + end + private def display_exp return unless power_numerator - "^#{power_numerator}" if power_numerator != "1" + exp = power_numerator.raw_value + "^#{exp}" if exp != "1" end def system_reference unit_instance.unit_system_reference end + + def msup_tag(value, options) + msup = ::Mml::Msup.new + msup.ordered = true + msup.element_order = [] + [value, power_numerator.to_mathml(options)].flatten.each do |record| + values = msup.public_send("#{record[:method_name]}_value") || [] + values += [record[:value]] + msup.element_order << Lutaml::Model::Xml::Element.new("Element", record[:method_name].to_s) + msup.public_send("#{record[:method_name]}_value=", values) + end + msup + end end end diff --git a/lib/unitsml/unitsdb.rb b/lib/unitsml/unitsdb.rb index 7e713d4..60599bd 100644 --- a/lib/unitsml/unitsdb.rb +++ b/lib/unitsml/unitsdb.rb @@ -9,19 +9,19 @@ def load_file(file_name) end def units - @@units_file ||= get_class_from_register(:unitsdb_units).from_yaml(load_file(:units)) + @@units_file ||= Unitsml.get_class_from_register(:unitsdb_units).from_yaml(load_file(:units)) end def prefixes - @@prefixes ||= get_class_from_register(:unitsdb_prefixes).from_yaml(load_file(:prefixes)) + @@prefixes ||= Unitsml.get_class_from_register(:unitsdb_prefixes).from_yaml(load_file(:prefixes)) end def dimensions - @@dim_file ||= get_class_from_register(:unitsdb_dimensions).from_yaml(load_file(:dimensions)) + @@dim_file ||= Unitsml.get_class_from_register(:unitsdb_dimensions).from_yaml(load_file(:dimensions)) end def quantities - @@quantities ||= get_class_from_register(:unitsdb_quantities).from_yaml(load_file(:quantities)) + @@quantities ||= Unitsml.get_class_from_register(:unitsdb_quantities).from_yaml(load_file(:quantities)) end def prefixes_array @@ -40,10 +40,6 @@ def valid_path(file_name) File.join(__dir__, "..", "..","unitsdb", "#{file_name}.yaml") ) end - - def get_class_from_register(class_name) - Unitsml.register.get_class(class_name) - end end end end diff --git a/lib/unitsml/unitsdb/dimensions.rb b/lib/unitsml/unitsdb/dimensions.rb index 70b693f..7ea4163 100644 --- a/lib/unitsml/unitsdb/dimensions.rb +++ b/lib/unitsml/unitsdb/dimensions.rb @@ -31,4 +31,4 @@ def find(field, matching_data) end end -Unitsml.register.register_model(Unitsml::Unitsdb::Dimensions, id: :unitsdb_dimensions) +Unitsml.register_model(Unitsml::Unitsdb::Dimensions, id: :unitsdb_dimensions) diff --git a/lib/unitsml/unitsdb/prefixes.rb b/lib/unitsml/unitsdb/prefixes.rb index c57240a..085b1a2 100644 --- a/lib/unitsml/unitsdb/prefixes.rb +++ b/lib/unitsml/unitsdb/prefixes.rb @@ -33,4 +33,4 @@ def find(matching_data, field, prefix_method) end end -Unitsml.register.register_model(Unitsml::Unitsdb::Prefixes, id: :unitsdb_prefixes) +Unitsml.register_model(Unitsml::Unitsdb::Prefixes, id: :unitsdb_prefixes) diff --git a/lib/unitsml/unitsdb/quantities.rb b/lib/unitsml/unitsdb/quantities.rb index c0492f0..e55d36e 100644 --- a/lib/unitsml/unitsdb/quantities.rb +++ b/lib/unitsml/unitsdb/quantities.rb @@ -12,4 +12,4 @@ def find_by_id(q_id) end end -Unitsml.register.register_model(Unitsml::Unitsdb::Quantities, id: :unitsdb_quantities) +Unitsml.register_model(Unitsml::Unitsdb::Quantities, id: :unitsdb_quantities) diff --git a/lib/unitsml/unitsdb/units.rb b/lib/unitsml/unitsdb/units.rb index 3a9fe6d..b538130 100644 --- a/lib/unitsml/unitsdb/units.rb +++ b/lib/unitsml/unitsdb/units.rb @@ -44,4 +44,4 @@ def find(matching_data, field, unit_method) end end -Unitsml.register.register_model(Unitsml::Unitsdb::Units, id: :unitsdb_units) +Unitsml.register_model(Unitsml::Unitsdb::Units, id: :unitsdb_units) diff --git a/lib/unitsml/utility.rb b/lib/unitsml/utility.rb index f537e3a..73f6447 100644 --- a/lib/unitsml/utility.rb +++ b/lib/unitsml/utility.rb @@ -23,7 +23,7 @@ module Utility "deg" => { dimension: "PlaneAngle", order: 8, symbol: "phi" }, }.freeze # Dimesion for dim_(dimesion) input - Dim2D = { + DIM2D = { "dim_L" => U2D["m"], "dim_M" => U2D["g"], "dim_T" => U2D["s"], @@ -44,6 +44,8 @@ module Utility Time ].freeze + UNKNOWN = "unknown" + class << self def unit_instance(unit) Unitsdb.units.find_by_symbol_id(unit) @@ -55,7 +57,7 @@ def quantity_instance(id) def units2dimensions(units) norm = decompose_units_list(units) - return if norm.any? { |u| u.nil? || u[:unit].unit_name == "unknown" || u[:prefix] == "unknown" } + return if norm.any? { |u| u.nil? || u[:unit]&.unknown_name? || u[:prefix] == UNKNOWN } norm.map do |u| unit_name = u[:unit].unit_name @@ -76,11 +78,18 @@ def dim_id(dims) 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])) + (U2D.dig(d[:unit], :symbol) || DIM2D.dig(d[:id], :symbol)) + + (to_i_value(d[:exponent]) == 1 ? "" : float_to_display(d[:exponent])) end.join("") end + def to_i_value(object) + case object + when Integer, Float then object + when Number, Fenced then object.to_i + end + end + def decompose_units_list(units) gather_units(units.map { |u| decompose_unit(u) }.flatten) end @@ -89,7 +98,7 @@ 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") } + { unit: Unit.new(UNKNOWN) } else u.si_derived_bases.each_with_object([]) do |k, object| prefix = if !k.prefix_reference.nil? @@ -111,7 +120,7 @@ def gather_units(units) 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][:unit]&.power_numerator = Number.new(numerator_value(k, m)) m[-1] = { prefix: combine_prefixes(prefix_object(m[-1][:prefix]), prefix_object(k[:prefix])), unit: m[-1][:unit], @@ -120,6 +129,15 @@ def gather_units(units) end end + def numerator_value(unit_hash, unit_array) + unit_numerator_float(unit_hash) + + unit_numerator_float(unit_array[-1]) + end + + def unit_numerator_float(object_hash) + object_hash[:unit]&.power_numerator&.to_f || 1 + end + def prefix_object(prefix) return prefix unless prefix.is_a?(String) return nil unless Unitsdb.prefixes_array.any?(prefix) @@ -131,14 +149,14 @@ 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 + 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" + UNKNOWN end def unit(units, formula, dims, norm_text, name, options) @@ -182,7 +200,7 @@ def unitsystem(units) 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')) + ret << Model::Units::System.new(name: "SI", type: (base ? "SI_base" : "SI_derived")) end ret end @@ -201,12 +219,17 @@ def dimension1(dim, dims_hash) 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]) + power_numerator: float_to_display(dim[:exponent]), ) end def float_to_display(float) - float.to_f.round(1).to_s.sub(/\.0$/, "") + case float + when Integer, Float + float.to_f.round(1).to_s.sub(/\.0$/, "") + when Number, Fenced + float.float_to_display + end end def dimid2dimensions(normtext) @@ -225,7 +248,7 @@ def dimid2dimensions(normtext) end def prefixes(units, options) - uniq_prefixes = units.map { |unit| unit.prefix }.compact.uniq { |d| d.prefix_name } + uniq_prefixes = units.map(&:prefix).compact.uniq(&: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 } @@ -247,7 +270,7 @@ def rootunits(units) 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 + attributes[:power_numerator] = unit.power_numerator.raw_value Model::Units::EnumeratedRootUnit.new(attributes) end Model::Units::RootUnits.new(enumerated_root_unit: enum_root_units) @@ -257,7 +280,13 @@ def unit_id(text) text = text&.gsub(/[()]/, "") unit = unit_instance(text) - "U_#{unit ? unit.nist_id&.gsub(/'/, '_') : text&.gsub(/\*/, '.')&.gsub(/\^/, '')}" + format_unit_id(unit, text)&.insert(0, "U_") + end + + def format_unit_id(unit, text) + return unit.nist_id&.gsub(/'/, "_") if unit + + text&.gsub(/\*/, ".")&.gsub(/\^/, "") end def dimension_components(dims) @@ -268,16 +297,26 @@ def dimension_components(dims) Model::Dimension.new(dim_attrs).to_xml end - def quantity(normtext, quantity) + def quantity(normtext, instance) unit = unit_instance(normtext) - return unless unit && unit.quantity_references.size == 1 || + return unless unit_or_quantity(unit, instance) + + model_quantity_xml( + (instance || unit.quantity_references&.first&.id), + "##{unit.dimension_url}", + ) + end + + def unit_or_quantity(unit, quantity) + unit && unit.quantity_references.size == 1 || quantity_instance(quantity) + end - id = (quantity || unit.quantity_references&.first&.id) + def model_quantity_xml(id, url) Model::Quantity.new( id: id, name: quantity_name(id), - dimension_url: "##{unit.dimension_url}", + dimension_url: url, ).to_xml end @@ -291,7 +330,7 @@ def quantity_name(id) def string_to_html_entity(string) HTMLEntities.new.encode( - string.frozen? ? string : string.force_encoding('UTF-8'), + string.frozen? ? string : string.force_encoding("UTF-8"), :hexadecimal, ) end diff --git a/spec/unitsml/conv/asciimath_spec.rb b/spec/unitsml/conv/asciimath_spec.rb index 437aeb3..5936016 100644 --- a/spec/unitsml/conv/asciimath_spec.rb +++ b/spec/unitsml/conv/asciimath_spec.rb @@ -9,9 +9,9 @@ end context "contains Unitsml #1 example" do - let(:exp) { "unitsml(mm*s^-2)" } + let(:exp) { "unitsml(mm*s^((-2)))" } + let(:expected_value) { "mm*s^(-2)" } - let(:expected_value) { "mm*s^-2" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -19,8 +19,8 @@ context "contains Unitsml #2 example" do let(:exp) { "unitsml(um)" } - let(:expected_value) { "um" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -28,8 +28,8 @@ context "contains Unitsml #3 example" do let(:exp) { "unitsml(degK)" } - let(:expected_value) { "degK" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -37,8 +37,8 @@ context "contains Unitsml #4 example" do let(:exp) { "unitsml(prime)" } - let(:expected_value) { "'" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -46,8 +46,8 @@ context "contains Unitsml #5 example" do let(:exp) { "unitsml(rad)" } - let(:expected_value) { "rad" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -55,8 +55,8 @@ context "contains Unitsml #6 example" do let(:exp) { "unitsml(Hz)" } - let(:expected_value) { "Hz" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -64,8 +64,8 @@ context "contains Unitsml #7 example" do let(:exp) { "unitsml(kg)" } - let(:expected_value) { "kg" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -73,8 +73,8 @@ context "contains Unitsml #8 example" do let(:exp) { "unitsml(m)" } - let(:expected_value) { "m" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -82,8 +82,8 @@ context "contains Unitsml #9 example" do let(:exp) { "unitsml(sqrt(Hz))" } - let(:expected_value) { "Hz^0.5" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -91,8 +91,8 @@ context "contains Unitsml #10 example" do let(:exp) { "unitsml(g)" } - let(:expected_value) { "g" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -100,8 +100,8 @@ context "contains Unitsml #11 example" do let(:exp) { "unitsml(hp)" } - let(:expected_value) { "hp" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -109,8 +109,8 @@ context "contains Unitsml #12 example" do let(:exp) { "unitsml(kg*s^-2)" } - let(:expected_value) { "kg*s^-2" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -118,8 +118,8 @@ context "contains Unitsml #13 example" do let(:exp) { "unitsml(mbar)" } - let(:expected_value) { "mbar" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -127,8 +127,8 @@ context "contains Unitsml #14 example" do let(:exp) { "unitsml(p-)" } - let(:expected_value) { "p" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -136,8 +136,8 @@ context "contains Unitsml #15 example" do let(:exp) { "unitsml(h-)" } - let(:expected_value) { "h" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -145,8 +145,8 @@ context "contains Unitsml #16 example" do let(:exp) { "unitsml(da-)" } - let(:expected_value) { "da" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -154,8 +154,8 @@ context "contains Unitsml #17 example" do let(:exp) { "unitsml(u-)" } - let(:expected_value) { "u" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -163,8 +163,8 @@ context "contains Unitsml #18 example" do let(:exp) { "unitsml(A*C^3)" } - let(:expected_value) { "A*C^3" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -172,8 +172,8 @@ context "contains Unitsml #19 example" do let(:exp) { "unitsml(A/C^-3)" } - let(:expected_value) { "A/C^3" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -181,8 +181,8 @@ context "contains Unitsml #20 example" do let(:exp) { "unitsml(J/kg*K)" } - let(:expected_value) { "J/kg^-1*K^-1" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -190,8 +190,8 @@ context "contains Unitsml #21 example" do let(:exp) { "unitsml(kg^-2)" } - let(:expected_value) { "kg^-2" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -199,26 +199,26 @@ context "contains Unitsml #22 example" do let(:exp) { "unitsml(kg*s^-2)" } - let(:expected_value) { "kg*s^-2" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end end context "contains Unitsml #23 example" do - let(:exp) { "unitsml(mW*cm^(-2))" } + let(:exp) { "unitsml(mW*cm^((-2)))" } + let(:expected_value) { "mW*cm^(-2)" } - let(:expected_value) { "mW*cm^-2" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end end context "contains Unitsml #24 example" do - let(:exp) { "unitsml(dim_Theta*dim_L^2)" } + let(:exp) { "unitsml(dim_Theta*dim_L^((2)))" } + let(:expected_value) { "Theta*L^(2)" } - let(:expected_value) { "Theta*L^2" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -226,8 +226,8 @@ context "contains Unitsml #25 example" do let(:exp) { "unitsml(dim_Theta^10*dim_L^2)" } - let(:expected_value) { "Theta^10*L^2" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -235,8 +235,8 @@ context "contains Unitsml #26 example" do let(:exp) { "unitsml(Hz^10*darcy^100, multiplier: xx)" } - let(:expected_value) { "Hz^10xxd^100" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -244,8 +244,8 @@ context "contains Unitsml #27 example" do let(:exp) { "unitsml(((Hz^10))*(darcy^100), multiplier: xx)" } - let(:expected_value) { "(Hz^10)xxd^100" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to eq(expected_value) end @@ -272,8 +272,8 @@ end context "implicit extender example #2 from issue#53" do - let(:exp) { "unitsml(J kg^-1 * K^-1)" } - let(:expected_value) { "J kg^-1*K^-1" } + let(:exp) { "unitsml(J kg^-1 * K^((-1)))" } + let(:expected_value) { "J kg^-1*K^(-1)" } it "matches the UnitsML to AsciiMath converted value" do expect(formula).to eq(expected_value) diff --git a/spec/unitsml/conv/html_spec.rb b/spec/unitsml/conv/html_spec.rb index 7bae447..a2c660d 100644 --- a/spec/unitsml/conv/html_spec.rb +++ b/spec/unitsml/conv/html_spec.rb @@ -9,9 +9,9 @@ end context "contains Unitsml #1 example" do - let(:exp) { "unitsml(mm*s^-2)" } + let(:exp) { "unitsml(mm*s^((-2)))" } + let(:expected_value) { "mm⋅s(−2)" } - let(:expected_value) { "mm⋅s−2" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -19,8 +19,8 @@ context "contains Unitsml #2 example" do let(:exp) { "unitsml(um)" } - let(:expected_value) { "µm" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -28,8 +28,8 @@ context "contains Unitsml #3 example" do let(:exp) { "unitsml(degK)" } - let(:expected_value) { "°K" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -37,8 +37,8 @@ context "contains Unitsml #4 example" do let(:exp) { "unitsml(prime)" } - let(:expected_value) { "′" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -46,8 +46,8 @@ context "contains Unitsml #5 example" do let(:exp) { "unitsml(rad)" } - let(:expected_value) { "rad" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -55,8 +55,8 @@ context "contains Unitsml #6 example" do let(:exp) { "unitsml(Hz)" } - let(:expected_value) { "Hz" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -64,8 +64,8 @@ context "contains Unitsml #7 example" do let(:exp) { "unitsml(kg)" } - let(:expected_value) { "kg" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -73,8 +73,8 @@ context "contains Unitsml #8 example" do let(:exp) { "unitsml(m)" } - let(:expected_value) { "m" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -82,8 +82,8 @@ context "contains Unitsml #9 example" do let(:exp) { "unitsml(sqrt(Hz))" } - let(:expected_value) { "Hz0.5" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -91,8 +91,8 @@ context "contains Unitsml #10 example" do let(:exp) { "unitsml(g)" } - let(:expected_value) { "g" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -100,17 +100,17 @@ context "contains Unitsml #11 example" do let(:exp) { "unitsml(hp)" } - let(:expected_value) { "hp" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end end context "contains Unitsml #12 example" do - let(:exp) { "unitsml(kg*s^-2)" } + let(:exp) { "unitsml(kg*s^(((-2))))" } + let(:expected_value) { "kg⋅s(−2)" } - let(:expected_value) { "kg⋅s−2" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -118,8 +118,8 @@ context "contains Unitsml #13 example" do let(:exp) { "unitsml(mbar)" } - let(:expected_value) { "mbar" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -127,8 +127,8 @@ context "contains Unitsml #14 example" do let(:exp) { "unitsml(p-)" } - let(:expected_value) { "p" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -136,8 +136,8 @@ context "contains Unitsml #15 example" do let(:exp) { "unitsml(h-)" } - let(:expected_value) { "h" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -145,8 +145,8 @@ context "contains Unitsml #16 example" do let(:exp) { "unitsml(da-)" } - let(:expected_value) { "da" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -154,8 +154,8 @@ context "contains Unitsml #17 example" do let(:exp) { "unitsml(u-)" } - let(:expected_value) { "µ" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -163,8 +163,8 @@ context "contains Unitsml #18 example" do let(:exp) { "unitsml(A*C^3)" } - let(:expected_value) { "A⋅C3" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -172,8 +172,8 @@ context "contains Unitsml #19 example" do let(:exp) { "unitsml(A/C^-3)" } - let(:expected_value) { "A⋅C3" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -181,8 +181,8 @@ context "contains Unitsml #20 example" do let(:exp) { "unitsml(J/kg*K)" } - let(:expected_value) { "J⋅kg−1⋅K−1" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -190,8 +190,8 @@ context "contains Unitsml #21 example" do let(:exp) { "unitsml(kg^-2)" } - let(:expected_value) { "kg−2" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -199,8 +199,8 @@ context "contains Unitsml #22 example" do let(:exp) { "unitsml(kg*s^-2)" } - let(:expected_value) { "kg⋅s−2" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -208,17 +208,17 @@ context "contains Unitsml #23 example" do let(:exp) { "unitsml(mW*cm^(-2))" } - let(:expected_value) { "mW⋅cm−2" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end end context "contains Unitsml #24 example" do - let(:exp) { "unitsml(dim_Theta*dim_L^2)" } + let(:exp) { "unitsml(dim_Theta*dim_L^((((2)))))" } + let(:expected_value) { "𝝠⋅𝖫((2))" } - let(:expected_value) { "𝝠⋅𝖫2" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -226,8 +226,8 @@ context "contains Unitsml #25 example" do let(:exp) { "unitsml(dim_Theta^10*dim_L^2)" } - let(:expected_value) { "𝝠10⋅𝖫2" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -235,8 +235,8 @@ context "contains Unitsml #26 example" do let(:exp) { "unitsml(Hz^10*darcy^100)" } - let(:expected_value) { "Hz10⋅d100" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -244,8 +244,8 @@ context "contains Unitsml #27 example" do let(:exp) { "unitsml(kcal_IT)" } - let(:expected_value) { "kcalIT" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -253,8 +253,8 @@ context "contains Unitsml #28 example" do let(:exp) { "unitsml(kcal_IT^100)" } - let(:expected_value) { "kcalIT100" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -262,8 +262,8 @@ context "contains Unitsml #29 example" do let(:exp) { "unitsml(dim_Theta^10*((dim_L^2)))" } - let(:expected_value) { "𝝠10⋅(𝖫2)" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end @@ -271,8 +271,8 @@ context "contains Unitsml #30 example" do let(:exp) { "unitsml(Hz^10*((darcy^100)))" } - let(:expected_value) { "Hz10⋅(d100)" } + it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) end diff --git a/spec/unitsml/conv/latex_spec.rb b/spec/unitsml/conv/latex_spec.rb index b128061..6783b88 100644 --- a/spec/unitsml/conv/latex_spec.rb +++ b/spec/unitsml/conv/latex_spec.rb @@ -9,8 +9,8 @@ end context "contains Unitsml #1 example" do - let(:exp) { "unitsml(mm*s^-2)" } - let(:expected_value) { "m\\ensuremath{\\mathrm{m}}/\\ensuremath{\\mathrm{s}}^-2" } + let(:exp) { "unitsml(mm*s^((-2)))" } + let(:expected_value) { "m\\ensuremath{\\mathrm{m}}/\\ensuremath{\\mathrm{s}}^(-2)" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) @@ -108,8 +108,8 @@ end context "contains Unitsml #12 example" do - let(:exp) { "unitsml(kg*s^-2)" } - let(:expected_value) { "k\\ensuremath{\\mathrm{g}}/\\ensuremath{\\mathrm{s}}^-2" } + let(:exp) { "unitsml(kg*s^((-2)))" } + let(:expected_value) { "k\\ensuremath{\\mathrm{g}}/\\ensuremath{\\mathrm{s}}^(-2)" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) @@ -216,8 +216,8 @@ end context "contains Unitsml #24 example" do - let(:exp) { "unitsml(dim_Theta*dim_L^2)" } - let(:expected_value) { "\\ensuremath{\\mathsf{\\Theta}}/\\ensuremath{\\mathsf{L}}^2" } + let(:exp) { "unitsml(dim_Theta*dim_L^((2)))" } + let(:expected_value) { "\\ensuremath{\\mathsf{\\Theta}}/\\ensuremath{\\mathsf{L}}^(2)" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) @@ -225,8 +225,8 @@ end context "contains Unitsml #25 example" do - let(:exp) { "unitsml(dim_Theta^10*dim_L^2)" } - let(:expected_value) { "\\ensuremath{\\mathsf{\\Theta}}^10/\\ensuremath{\\mathsf{L}}^2" } + let(:exp) { "unitsml(dim_Theta^10*dim_L^((((2)))))" } + let(:expected_value) { "\\ensuremath{\\mathsf{\\Theta}}^10/\\ensuremath{\\mathsf{L}}^((2))" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) @@ -299,8 +299,8 @@ end context "implicit extender example #2 from issue#53" do - let(:exp) { "unitsml(J kg^-1 * K^-1)" } - let(:expected_value) { "\\ensuremath{\\mathrm{J}}/k\\ensuremath{\\mathrm{g}}^-1/\\ensuremath{\\mathrm{K}}^-1" } + let(:exp) { "unitsml(J kg^-1 * K^((-1)))" } + let(:expected_value) { "\\ensuremath{\\mathrm{J}}/k\\ensuremath{\\mathrm{g}}^-1/\\ensuremath{\\mathrm{K}}^(-1)" } it "matches the UnitsML to LaTeX converted value" do expect(formula).to eq(expected_value) diff --git a/spec/unitsml/conv/mathml_spec.rb b/spec/unitsml/conv/mathml_spec.rb index 4bdd634..83787a0 100644 --- a/spec/unitsml/conv/mathml_spec.rb +++ b/spec/unitsml/conv/mathml_spec.rb @@ -8,7 +8,7 @@ subject(:mathml) { formula.to_mathml } context "contains Unitsml #1 example" do - let(:exp) { "unitsml(mm*s^-2)" } + let(:exp) { "unitsml(mm*s^((-2)))" } let(:expected_value) do <<~MATHML @@ -16,12 +16,14 @@ mm + s - s - - - - 2 + ( + + + 2 + + ) @@ -144,12 +146,8 @@ <<~MATHML - - Hz - - - 0.5 - + Hz + 0.5 MATHML @@ -190,7 +188,7 @@ end context "contains Unitsml #12 example" do - let(:exp) { "unitsml(kg*s^-2)" } + let(:exp) { "unitsml(kg*s^(-2))" } let(:expected_value) do <<~MATHML @@ -198,9 +196,7 @@ kg - - s - + s 2 @@ -298,12 +294,8 @@ A - - C - - - 3 - + C + 3 MATHML @@ -322,12 +314,8 @@ A - - C - - - 3 - + C + 3 MATHML @@ -346,9 +334,7 @@ J - - kg - + kg 1 @@ -356,9 +342,7 @@ - - K - + K 1 @@ -379,9 +363,7 @@ <<~MATHML - - kg - + kg 2 @@ -404,9 +386,7 @@ kg - - s - + s 2 @@ -429,9 +409,7 @@ mW - - cm - + cm 2 @@ -446,7 +424,7 @@ end context "contains Unitsml #24 example" do - let(:exp) { "unitsml(dim_Theta*dim_L^2)" } + let(:exp) { "unitsml(dim_Theta*dim_L^((((2)))))" } let(:expected_value) do <<~MATHML @@ -458,7 +436,13 @@ L - 2 + ( + + ( + 2 + ) + + ) @@ -470,7 +454,7 @@ end context "contains Unitsml #25 example" do - let(:exp) { "unitsml(dim_Theta^10*dim_L^2)" } + let(:exp) { "unitsml(dim_Theta^10*dim_L^(2))" } let(:expected_value) do <<~MATHML @@ -479,22 +463,19 @@ Θ - - 10 - + 10 L - - 2 - + 2 MATHML end + it "returns parslet tree of parsed Unitsml string" do expect(mathml).to be_equivalent_to(expected_value) end @@ -507,21 +488,13 @@ <<~MATHML - - Hz - - - 10 - + Hz + 10 - - d - - - 100 - + d + 100 MATHML @@ -593,7 +566,7 @@ end context "contains plurimath/plurimath#356 Unitsml #28 example" do - let(:exp) { "unitsml(kg*m^-1*s^-1*K^(-1//2))" } + let(:exp) { "unitsml(kg*m^-1*s^-1*K^(((-1//2))))" } let(:expected_value) do <<~MATHML @@ -601,9 +574,7 @@ kg - - m - + m 1 @@ -611,9 +582,7 @@ - - s - + s 1 @@ -621,12 +590,14 @@ + K - K - - - - 1//2 + ( + + + 1//2 + + ) @@ -701,16 +672,14 @@ end context "implicit extender example #2 from issue#53" do - let(:exp) { "unitsml(J kg^-1 * K^-1)" } + let(:exp) { "unitsml(J kg^-1 * K^((-1)))" } let(:expected_value) do <<~MATHML J - - kg - + kg 1 @@ -718,12 +687,14 @@ + K - K - - - - 1 + ( + + + 1 + + ) @@ -743,9 +714,7 @@ J - - mol - + mol 1 @@ -753,9 +722,7 @@ - - K - + K 1 @@ -778,9 +745,7 @@ J - - mol - + mol 1 @@ -788,9 +753,7 @@ - - K - + K 1 diff --git a/spec/unitsml/conv/plurimath_spec.rb b/spec/unitsml/conv/plurimath_spec.rb index 47e2d17..63be38d 100644 --- a/spec/unitsml/conv/plurimath_spec.rb +++ b/spec/unitsml/conv/plurimath_spec.rb @@ -19,7 +19,7 @@ end context "Unitsml example contains prefix and units" do - let(:exp) { "unitsml(mm*s^-2)" } + let(:exp) { "unitsml(mm*s^((-2)))" } let(:expected_value) do Plurimath::Math::Formula.new([ Plurimath::Math::Function::FontStyle::Normal.new( @@ -32,10 +32,16 @@ Plurimath::Math::Symbols::Symbol.new("s"), "normal" ), - Plurimath::Math::Formula.new([ - Plurimath::Math::Symbols::Minus.new, - Plurimath::Math::Number.new("2") - ]) + Plurimath::Math::Function::Fenced.new( + Plurimath::Math::Symbols::Paren::Lround.new, + [ + Plurimath::Math::Formula.new([ + Plurimath::Math::Symbols::Minus.new, + Plurimath::Math::Number.new("2"), + ]), + ], + Plurimath::Math::Symbols::Paren::Rround.new, + ), ) ]) end @@ -107,7 +113,7 @@ end context "Unitsml example crashing in plurimath/plurimath#343" do - let(:exp) { "unitsml(kg^(-1)*m^(-3)*s^4*A^2)" } + let(:exp) { "unitsml(kg^((-1))*m^((-3))*s^4*A^2)" } let(:expected_value) do Plurimath::Math::Formula.new( [ @@ -116,10 +122,16 @@ Plurimath::Math::Symbols::Symbol.new("kg"), "normal", ), - Plurimath::Math::Formula.new([ - Plurimath::Math::Symbols::Minus.new, - Plurimath::Math::Number.new("1"), - ]) + Plurimath::Math::Function::Fenced.new( + Plurimath::Math::Symbols::Paren::Lround.new, + [ + Plurimath::Math::Formula.new([ + Plurimath::Math::Symbols::Minus.new, + Plurimath::Math::Number.new("1"), + ]), + ], + Plurimath::Math::Symbols::Paren::Rround.new, + ), ), Plurimath::Math::Symbols::Cdot.new, Plurimath::Math::Function::Power.new( @@ -127,10 +139,16 @@ Plurimath::Math::Symbols::Symbol.new("m"), "normal", ), - Plurimath::Math::Formula.new([ - Plurimath::Math::Symbols::Minus.new, - Plurimath::Math::Number.new("3"), - ]) + Plurimath::Math::Function::Fenced.new( + Plurimath::Math::Symbols::Paren::Lround.new, + [ + Plurimath::Math::Formula.new([ + Plurimath::Math::Symbols::Minus.new, + Plurimath::Math::Number.new("3"), + ]), + ], + Plurimath::Math::Symbols::Paren::Rround.new, + ), ), Plurimath::Math::Symbols::Cdot.new, Plurimath::Math::Function::Power.new( @@ -158,7 +176,7 @@ end context "Unitsml example contains unit only wrapped in parentheses with default explicit_parenthesis: true" do - let(:exp) { "unitsml(((((g)))))" } + let(:exp) { "unitsml(((((g^((((3)))))))))" } let(:expected_value) do Plurimath::Math::Formula.new([ Plurimath::Math::Function::Fenced.new( @@ -167,9 +185,24 @@ Plurimath::Math::Function::Fenced.new( Plurimath::Math::Symbols::Paren::Lround.new, [ - Plurimath::Math::Function::FontStyle::Normal.new( - Plurimath::Math::Symbols::Symbol.new("g"), - "normal", + Plurimath::Math::Function::Power.new( + Plurimath::Math::Function::FontStyle::Normal.new( + Plurimath::Math::Symbols::Symbol.new("g"), + "normal", + ), + Plurimath::Math::Function::Fenced.new( + Plurimath::Math::Symbols::Paren::Lround.new, + [ + Plurimath::Math::Function::Fenced.new( + Plurimath::Math::Symbols::Paren::Lround.new, + [ + Plurimath::Math::Number.new("3"), + ], + Plurimath::Math::Symbols::Paren::Rround.new, + ), + ], + Plurimath::Math::Symbols::Paren::Rround.new, + ), ), ], Plurimath::Math::Symbols::Paren::Rround.new, @@ -235,7 +268,7 @@ end context "implicit extender example #2 from issue#53" do - let(:exp) { "unitsml(J kg^-1 * K^-1)" } + let(:exp) { "unitsml(J kg^((-1)) * K^(((-1))))" } let(:expected_value) do Plurimath::Math::Formula.new([ Plurimath::Math::Function::FontStyle::Normal.new( @@ -248,10 +281,16 @@ Plurimath::Math::Symbols::Symbol.new("kg"), "normal", ), - Plurimath::Math::Formula.new([ - Plurimath::Math::Symbols::Minus.new, - Plurimath::Math::Number.new("1"), - ]) + Plurimath::Math::Function::Fenced.new( + Plurimath::Math::Symbols::Paren::Lround.new, + [ + Plurimath::Math::Formula.new([ + Plurimath::Math::Symbols::Minus.new, + Plurimath::Math::Number.new("1"), + ]), + ], + Plurimath::Math::Symbols::Paren::Rround.new, + ), ), Plurimath::Math::Symbols::Cdot.new, Plurimath::Math::Function::Power.new( @@ -259,10 +298,16 @@ Plurimath::Math::Symbols::Symbol.new("K"), "normal", ), - Plurimath::Math::Formula.new([ - Plurimath::Math::Symbols::Minus.new, - Plurimath::Math::Number.new("1"), - ]), + Plurimath::Math::Function::Fenced.new( + Plurimath::Math::Symbols::Paren::Lround.new, + [ + Plurimath::Math::Formula.new([ + Plurimath::Math::Symbols::Minus.new, + Plurimath::Math::Number.new("1"), + ]), + ], + Plurimath::Math::Symbols::Paren::Rround.new, + ), ) ]) end @@ -678,7 +723,7 @@ end context "implicit extender example #15" do - let(:exp) { "unitsml(sqrt(dim_phi(dim_I)) ((dim_Theta) dim_L))" } + let(:exp) { "unitsml(sqrt(dim_phi(dim_I)) ((dim_Theta) dim_L^((12))))" } let(:expected_value) do Plurimath::Math::Formula.new([ Plurimath::Math::Function::FontStyle::SansSerif.new( @@ -708,9 +753,18 @@ ], Plurimath::Math::Symbols::Paren::Rround.new, ), - Plurimath::Math::Function::FontStyle::SansSerif.new( - Plurimath::Math::Symbols::Symbol.new("L"), - "sans-serif", + Plurimath::Math::Function::Power.new( + Plurimath::Math::Function::FontStyle::SansSerif.new( + Plurimath::Math::Symbols::Symbol.new("L"), + "sans-serif", + ), + Plurimath::Math::Function::Fenced.new( + Plurimath::Math::Symbols::Paren::Lround.new, + [ + Plurimath::Math::Number.new("12"), + ], + Plurimath::Math::Symbols::Paren::Rround.new, + ), ), ], Plurimath::Math::Symbols::Paren::Rround.new, diff --git a/spec/unitsml/conv/unicode_spec.rb b/spec/unitsml/conv/unicode_spec.rb index 65ddd06..c955f1c 100644 --- a/spec/unitsml/conv/unicode_spec.rb +++ b/spec/unitsml/conv/unicode_spec.rb @@ -5,8 +5,8 @@ subject(:formula) { described_class.new(exp).parse.to_unicode(respond_to?(:options) ? options : {}) } context "contains Unitsml #1 example" do - let(:exp) { "unitsml(mm*s^-2)" } - let(:expected_value) { "mm·s^-2" } + let(:exp) { "unitsml(mm*s^((-2)))" } + let(:expected_value) { "mm·s^(-2)" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) @@ -221,8 +221,8 @@ end context "contains Unitsml #25 example" do - let(:exp) { "unitsml(dim_Theta^10*dim_L^2)" } - let(:expected_value) { "𝝧^10·𝖫^2" } + let(:exp) { "unitsml(dim_Theta^10*dim_L^((2)))" } + let(:expected_value) { "𝝧^10·𝖫^(2)" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) @@ -239,8 +239,8 @@ end context "contains Unitsml #27 example" do - let(:exp) { "unitsml(((Hz^10))*darcy^100)" } - let(:expected_value) { "(Hz^10)·d^100" } + let(:exp) { "unitsml(((Hz^10))*darcy^((((100)))))" } + let(:expected_value) { "(Hz^10)·d^((100))" } it "returns parslet tree of parsed Unitsml string" do expect(formula).to be_equivalent_to(expected_value) @@ -248,7 +248,7 @@ end context "contains Unitsml #27 example with explicit_parenthesis: false" do - let(:exp) { "unitsml((Hz^10)*darcy^100)" } + let(:exp) { "unitsml((Hz^10)*darcy^((((100)))))" } let(:expected_value) { "Hz^10·d^100" } let(:options) { { explicit_parenthesis: false } } diff --git a/spec/unitsml/conv/xml_spec.rb b/spec/unitsml/conv/xml_spec.rb index c7389b3..cab60fa 100644 --- a/spec/unitsml/conv/xml_spec.rb +++ b/spec/unitsml/conv/xml_spec.rb @@ -7,22 +7,36 @@ subject(:formula) { described_class.new(exp).parse } context "contains Unitsml #1 example" do - let(:exp) { "unitsml(mm*s^-2)" } + let(:exp) { "unitsml(mm*s^((-2)))" } let(:expected_value) do <<~XML - + mm*s^-2 - mm⋅s−2 - mms2 - + mm⋅s(−2) + + + mm + + + s + + ( + + + 2 + + ) + + + + - milli m @@ -31,8 +45,7 @@ m - - + @@ -279,12 +292,8 @@ - - Hz - - - 0.5 - + Hz + 0.5 @@ -367,7 +376,7 @@ let(:exp) { "unitsml(kg*s^-2)" } let(:expected_value) do <<~XML - + kg*s^-2 kg⋅s−2 @@ -376,9 +385,7 @@ kg - - s - + s 2 @@ -400,7 +407,7 @@ k - + @@ -566,12 +573,8 @@ A - - C - - - 3 - + C + 3 @@ -606,12 +609,8 @@ A - - C - - - 3 - + C + 3 @@ -646,9 +645,7 @@ J - - kg - + kg 1 @@ -656,9 +653,7 @@ - - K - + K 1 @@ -712,9 +707,7 @@ - - kg - + kg 2 @@ -750,7 +743,7 @@ let(:exp) { "unitsml(kg*s^-2)" } let(:expected_value) do <<~XML - + kg*s^-2 kg⋅s−2 @@ -759,9 +752,7 @@ kg - - s - + s 2 @@ -783,7 +774,7 @@ k - + @@ -808,9 +799,7 @@ mW - - cm - + cm 2 @@ -848,7 +837,7 @@ end context "contains Unitsml #24 example" do - let(:exp) { "unitsml(dim_Theta*dim_L^2)" } + let(:exp) { "unitsml(dim_Theta*dim_L^((2)))" } let(:expected_value) do <<~XML @@ -891,21 +880,13 @@ - - Hz - - - 10 - + Hz + 10 - - d - - - 100 - + d + 100 @@ -948,12 +929,8 @@ - - mm - - - 0.5 - + mm + 0.5 @@ -994,9 +971,7 @@ GHz - - V - + V 1 @@ -1036,16 +1011,14 @@ let(:exp) { "unitsml(m^(-2))" } let(:expected_value) do <<~XML - + meter to the power minus two m−2 - - m - + m 2 @@ -1059,6 +1032,10 @@ + + + + fluence @@ -1085,9 +1062,7 @@ sr - - m - + m 2 @@ -1167,9 +1142,7 @@ m - - kg - + kg 2 @@ -1207,9 +1180,7 @@ m - - kg - + kg 2 @@ -1247,9 +1218,7 @@ m X - - kg - + kg 2 @@ -1293,7 +1262,7 @@ let(:exp) { "unitsml((((m^-2))))" } let(:expected_value) do <<~XML - + meter to the power minus two (m−2) @@ -1302,9 +1271,7 @@ ( - - m - + m 2 @@ -1320,6 +1287,10 @@ + + + + fluence @@ -1348,19 +1319,17 @@ end context "contains Unitsml #36 example" do - let(:exp) { "unitsml((m^-2))" } + let(:exp) { "unitsml((m^((-2))))" } let(:expected_value) do <<~XML - + meter to the power minus two m−2 - - m - + m 2 @@ -1374,6 +1343,10 @@ + + + + fluence diff --git a/spec/unitsml/parse_spec.rb b/spec/unitsml/parse_spec.rb index 808b8a1..d892d58 100644 --- a/spec/unitsml/parse_spec.rb +++ b/spec/unitsml/parse_spec.rb @@ -12,7 +12,7 @@ expect(formula[:unit]).to eq("m") expect(formula[:extender]).to eq("*") expect(formula[:sequence][:unit]).to eq("s") - expect(formula[:sequence][:integer]).to eq("-2") + expect(formula[:sequence][:power_numerator][:integer]).to eq("-2") end end @@ -117,7 +117,7 @@ expect(formula[:unit]).to eq("g") expect(formula[:extender]).to eq("*") expect(sequence[:unit]).to eq("s") - expect(sequence[:integer]).to eq("-2") + expect(sequence[:power_numerator][:integer]).to eq("-2") end end @@ -179,7 +179,7 @@ expect(formula[:unit]).to eq("A") expect(formula[:extender]).to eq("*") expect(sequence[:unit]).to eq("C") - expect(sequence[:integer]).to eq("3") + expect(sequence[:power_numerator][:integer]).to eq("3") end end @@ -192,7 +192,7 @@ expect(formula[:unit]).to eq("A") expect(formula[:extender]).to eq("/") expect(sequence[:unit]).to eq("C") - expect(sequence[:integer]).to eq("-3") + expect(sequence[:power_numerator][:integer]).to eq("-3") end end @@ -217,7 +217,7 @@ it "returns parslet tree of parsed Unitsml string" do expect(formula[:prefix]).to eq("k") expect(formula[:unit]).to eq("g") - expect(formula[:integer]).to eq("-2") + expect(formula[:power_numerator][:integer]).to eq("-2") end end @@ -239,7 +239,7 @@ expect(formula[:unit]).to eq("g") expect(formula[:extender]).to eq("*") expect(sequence[:unit]).to eq("s") - expect(sequence[:integer]).to eq("-2") + expect(sequence[:power_numerator][:integer]).to eq("-2") end end @@ -254,7 +254,7 @@ expect(formula[:extender]).to eq("*") expect(sequence[:prefix]).to eq("c") expect(sequence[:unit]).to eq("m") - expect(sequence[:integer]).to eq("-2") + expect(sequence[:power_numerator][:int_exp][:integer]).to eq("-2") end end @@ -267,7 +267,7 @@ expect(formula[:dimension]).to eq("dim_Theta") expect(formula[:extender]).to eq("*") expect(sequence[:dimension]).to eq("dim_L") - expect(sequence[:integer]).to eq("2") + expect(sequence[:power_numerator][:integer]).to eq("2") end end @@ -278,10 +278,10 @@ sequence = formula[:sequence] expect(formula[:dimension]).to eq("dim_Theta") - expect(formula[:integer]).to eq("10") + expect(formula[:power_numerator][:integer]).to eq("10") expect(formula[:extender]).to eq("*") expect(sequence[:dimension]).to eq("dim_L") - expect(sequence[:integer]).to eq("2") + expect(sequence[:power_numerator][:integer]).to eq("2") end end @@ -290,10 +290,10 @@ it "returns parslet tree of parsed Unitsml string" do expect(formula[:unit]).to eq("Hz") - expect(formula[:integer]).to eq("10") + expect(formula[:power_numerator][:integer]).to eq("10") expect(formula[:extender]).to eq("*") expect(formula[:sequence][:unit]).to eq("darcy") - expect(formula[:sequence][:integer]).to eq("100") + expect(formula[:sequence][:power_numerator][:integer]).to eq("100") end end end diff --git a/spec/unitsml/parser_spec.rb b/spec/unitsml/parser_spec.rb index 6bc6cae..16dbe6b 100644 --- a/spec/unitsml/parser_spec.rb +++ b/spec/unitsml/parser_spec.rb @@ -12,9 +12,16 @@ Unitsml::Unit.new("K"), Unitsml::Extender.new("/"), Unitsml::Formula.new([ - Unitsml::Unit.new("g", "-1", prefix: Unitsml::Prefix.new("k")), + Unitsml::Unit.new( + "g", + Unitsml::Number.new("-1"), + prefix: Unitsml::Prefix.new("k"), + ), Unitsml::Extender.new("*"), - Unitsml::Unit.new("m", "-1"), + Unitsml::Unit.new( + "m", + Unitsml::Number.new("-1"), + ), ]) ], explicit_value: nil, @@ -55,7 +62,11 @@ [ Unitsml::Unit.new("cal_th"), Unitsml::Extender.new("/"), - Unitsml::Unit.new("m", "-2", prefix: Unitsml::Prefix.new("c")), + Unitsml::Unit.new( + "m", + Unitsml::Number.new("-2"), + prefix: Unitsml::Prefix.new("c"), + ), ], explicit_value: { name: "langley" }, norm_text: "cal_th/cm^2", @@ -95,9 +106,12 @@ [ Unitsml::Unit.new("m", prefix: Unitsml::Prefix.new("c")), Unitsml::Extender.new("*"), - Unitsml::Unit.new("s", "-2") + Unitsml::Unit.new( + "s", + Unitsml::Number.new("-2"), + ), ], - explicit_value: { symbol: "cm cdot s^-2"}, + explicit_value: { symbol: "cm cdot s^-2" }, root: true, orig_text: "cm*s^-2, symbol: cm cdot s^-2", norm_text: "cm*s^-2" @@ -116,7 +130,10 @@ [ Unitsml::Unit.new("m", prefix: Unitsml::Prefix.new("c")), Unitsml::Extender.new("*"), - Unitsml::Unit.new("s", "-2"), + Unitsml::Unit.new( + "s", + Unitsml::Number.new("-2"), + ), ], explicit_value: { multiplier: "xx" }, norm_text: "cm*s^-2", @@ -137,7 +154,10 @@ [ Unitsml::Unit.new("m", prefix: Unitsml::Prefix.new("m")), Unitsml::Extender.new("*"), - Unitsml::Unit.new("s", "-2"), + Unitsml::Unit.new( + "s", + Unitsml::Number.new("-2"), + ), ], root: true, orig_text: "mm*s^-2", @@ -282,7 +302,10 @@ Unitsml::Formula.new( [ Unitsml::Sqrt.new( - Unitsml::Unit.new("Hz", "0.5"), + Unitsml::Unit.new( + "Hz", + Unitsml::Number.new("0.5"), + ), ), ], norm_text: "sqrt(Hz)", @@ -339,7 +362,10 @@ [ Unitsml::Unit.new("g", prefix: Unitsml::Prefix.new("k")), Unitsml::Extender.new("*"), - Unitsml::Unit.new("s", "-2") + Unitsml::Unit.new( + "s", + Unitsml::Number.new("-2"), + ), ], norm_text: "kg*s^-2", orig_text: "kg*s^-2", @@ -449,7 +475,10 @@ [ Unitsml::Unit.new("A"), Unitsml::Extender.new("*"), - Unitsml::Unit.new("C", "3"), + Unitsml::Unit.new( + "C", + Unitsml::Number.new("3"), + ), ], norm_text: "A*C^3", orig_text: "A*C^3", @@ -469,7 +498,10 @@ [ Unitsml::Unit.new("A"), Unitsml::Extender.new("/"), - Unitsml::Unit.new("C", "3"), + Unitsml::Unit.new( + "C", + Unitsml::Number.new("3"), + ), ], norm_text: "A/C^-3", orig_text: "A/C^-3", @@ -490,9 +522,16 @@ Unitsml::Unit.new("J"), Unitsml::Extender.new("/"), Unitsml::Formula.new([ - Unitsml::Unit.new("g", "-1", prefix: Unitsml::Prefix.new("k")), + Unitsml::Unit.new( + "g", + Unitsml::Number.new("-1"), + prefix: Unitsml::Prefix.new("k"), + ), Unitsml::Extender.new("*"), - Unitsml::Unit.new("K", "-1"), + Unitsml::Unit.new( + "K", + Unitsml::Number.new("-1"), + ), ]) ], norm_text: "J/kg*K", @@ -511,7 +550,11 @@ let(:expected_value) do Unitsml::Formula.new( [ - Unitsml::Unit.new("g", "-2", prefix: Unitsml::Prefix.new("k")), + Unitsml::Unit.new( + "g", + Unitsml::Number.new("-2"), + prefix: Unitsml::Prefix.new("k"), + ), ], norm_text: "kg^-2", orig_text: "kg^-2", @@ -531,7 +574,11 @@ [ Unitsml::Unit.new("W", prefix: Unitsml::Prefix.new("m")), Unitsml::Extender.new("*"), - Unitsml::Unit.new("m", "-2", prefix: Unitsml::Prefix.new("c")), + Unitsml::Unit.new( + "m", + Unitsml::Number.new("-2"), + prefix: Unitsml::Prefix.new("c"), + ), ], norm_text: "mW*cm(-2)", orig_text: "mW*cm(-2)", @@ -551,7 +598,10 @@ [ Unitsml::Dimension.new("dim_Theta"), Unitsml::Extender.new("*"), - Unitsml::Dimension.new("dim_L", "2"), + Unitsml::Dimension.new( + "dim_L", + Unitsml::Number.new("2"), + ), ], norm_text: "dim_Theta*dim_L^2", orig_text: "dim_Theta*dim_L^2", @@ -569,9 +619,15 @@ let(:expected_value) do Unitsml::Formula.new( [ - Unitsml::Dimension.new("dim_Theta", "10"), + Unitsml::Dimension.new( + "dim_Theta", + Unitsml::Number.new("10"), + ), Unitsml::Extender.new("*"), - Unitsml::Dimension.new("dim_L", "2"), + Unitsml::Dimension.new( + "dim_L", + Unitsml::Number.new("2"), + ), ], norm_text: "dim_Theta^10*dim_L^2", orig_text: "dim_Theta^10*dim_L^2", @@ -589,9 +645,15 @@ let(:expected_value) do Unitsml::Formula.new( [ - Unitsml::Unit.new("Hz", "10"), + Unitsml::Unit.new( + "Hz", + Unitsml::Number.new("10"), + ), Unitsml::Extender.new("*"), - Unitsml::Unit.new("darcy", "-100"), + Unitsml::Unit.new( + "darcy", + Unitsml::Number.new("-100"), + ), ], norm_text: "Hz^10*darcy^-100", orig_text: "Hz^10*darcy^-100", @@ -611,7 +673,10 @@ [ Unitsml::Unit.new("W"), Unitsml::Extender.new("*"), - Unitsml::Unit.new("m", "-2"), + Unitsml::Unit.new( + "m", + Unitsml::Number.new("-2"), + ), ], norm_text: "W*m^(-2)", orig_text: "W*m^(-2)", @@ -751,17 +816,29 @@ [ Unitsml::Fenced.new( "(", - Unitsml::Dimension.new("dim_Theta", "12"), + Unitsml::Dimension.new( + "dim_Theta", + Unitsml::Number.new("12"), + ), ")", ), Unitsml::Extender.new("*"), Unitsml::Formula.new([ - Unitsml::Dimension.new("dim_N", "12"), + Unitsml::Dimension.new( + "dim_N", + Unitsml::Number.new("12"), + ), Unitsml::Extender.new("*"), Unitsml::Formula.new([ - Unitsml::Dimension.new("dim_J", "10"), + Unitsml::Dimension.new( + "dim_J", + Unitsml::Number.new("10"), + ), Unitsml::Extender.new("*"), - Unitsml::Dimension.new("dim_Theta", "10"), + Unitsml::Dimension.new( + "dim_Theta", + Unitsml::Number.new("10"), + ), ]), ]) ], @@ -786,9 +863,15 @@ Unitsml::Fenced.new( "(", Unitsml::Formula.new([ - Unitsml::Unit.new("A", "-1"), + Unitsml::Unit.new( + "A", + Unitsml::Number.new("-1"), + ), Unitsml::Extender.new("*"), - Unitsml::Unit.new("m", "-1"), + Unitsml::Unit.new( + "m", + Unitsml::Number.new("-1"), + ), ]), ")", ), @@ -848,13 +931,16 @@ Unitsml::Extender.new(" "), Unitsml::Unit.new( "g", - "-1", + Unitsml::Number.new("-1"), prefix: Unitsml::Prefix.new("k"), ), ], ), Unitsml::Extender.new("*"), - Unitsml::Unit.new("K", "-1"), + Unitsml::Unit.new( + "K", + Unitsml::Number.new("-1"), + ), ], norm_text: "J kg^-1 * K^-1", orig_text: "J kg^-1 * K^-1", @@ -876,9 +962,15 @@ Unitsml::Extender.new("/"), Unitsml::Formula.new( [ - Unitsml::Unit.new("mol", "-1"), + Unitsml::Unit.new( + "mol", + Unitsml::Number.new("-1"), + ), Unitsml::Extender.new("*"), - Unitsml::Unit.new("K", "-1"), + Unitsml::Unit.new( + "K", + Unitsml::Number.new("-1"), + ), ], ), ], @@ -902,9 +994,15 @@ Unitsml::Extender.new("/"), Unitsml::Formula.new( [ - Unitsml::Unit.new("mol", "-1"), + Unitsml::Unit.new( + "mol", + Unitsml::Number.new("-1"), + ), Unitsml::Extender.new("*"), - Unitsml::Unit.new("K", "-1"), + Unitsml::Unit.new( + "K", + Unitsml::Number.new("-1"), + ), ], ), ],