def self.from_string(string)
return nil if string.nil? || string.eql?(".") || string.eql?("")
stripped = string.gsub(/^"|["\n]+$/, "")
return nil unless stripped
cleaned = if /(U\.I\.|U\.)$/.match?(stripped)
stripped
else
stripped.sub(/\.+$/, "")
end
puts "ParseComposition.from_string #{string}" if VERBOSE_MESSAGES
cleaned = @@error_handler.apply_fixes(cleaned)
puts "ParseComposition.new cleaned #{cleaned}" if VERBOSE_MESSAGES && !cleaned.eql?(stripped)
CompositionTransformer.clear_substances
result = ParseComposition.new(cleaned)
parser = CompositionParser.new
transf = CompositionTransformer.new
begin
if defined?(RSpec)
ast = transf.apply(parser.parse_with_debug(cleaned))
puts "#{File.basename(__FILE__)}:#{__LINE__}: ==> " if VERBOSE_MESSAGES
pp ast if VERBOSE_MESSAGES
else
ast = transf.apply(parser.parse(cleaned))
end
rescue Parslet::ParseFailed => error
@@error_handler.nrParsingErrors ||= 0
@@error_handler.nrParsingErrors += 1
puts "#{File.basename(__FILE__)}:#{__LINE__}: failed parsing ==> #{cleaned} #{error}"
return nil
end
result.source = string
return result unless ast
return result if ast.is_a?(Parslet::Slice)
result.substances = CompositionTransformer.substances
result.excipiens = CompositionTransformer.excipiens
result.corresp = CompositionTransformer.corresp if CompositionTransformer.corresp
if result&.excipiens&.unit
pro_qty = "/#{result.excipiens.qty} #{result.excipiens.unit}".sub(/\/1\s+/, "/")
result.substances.each { |substance|
next unless substance.is_a?(ParseSubstance)
substance.chemical_substance.unit = "#{substance.chemical_substance.unit}#{pro_qty}" if substance.chemical_substance
substance.dose.unit = "#{substance.dose.unit}#{pro_qty}" if substance.unit && !substance.unit.eql?(result.excipiens.unit)
}
end
if ast.is_a?(Array) && ast.first.is_a?(Hash)
label = ast.first[:label].to_s if ast.first[:label]
label_description = ast.first[:label_description].to_s if ast.first[:label_description]
elsif ast&.is_a?(Hash)
label = ast[:label].to_s if ast[:label]
label_description = ast[:label_description].to_s if ast[:label_description]
end
if label
if label && !/((A|B|C|D|E|I|II|III|IV|\)+)\s+et\s+(A|B|C|D|E|I|II|III|IV|\))+)/.match(label)
result.label = label
end
result.label_description = label_description.gsub(/:+$/, "").strip if label_description
end
result.corresp = ast[:corresp].to_s.sub(/:\s+/, "") if !result.corresp && ast.is_a?(Hash) && ast[:corresp]
result
end