oddb2xml 2.0.7 → 2.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MDg2MTM3NzVmZDE3MjhkNjg5ODc3Y2IxNGJkYzVmYTBhMTYyNGI2MQ==
4
+ YTFjMTAzMzFiNjM4ZDMwOTUwMjYyMDI1YTZjZThjODBkZjU3MGE2MQ==
5
5
  data.tar.gz: !binary |-
6
- MmM2ZjRlNzA5NTYwNWIzZDc0MTZmNjcwZDA1NWZkOGEyYzY2MDY2NQ==
6
+ Y2JhOTEzZmE0MmI1YTc1NDRjZjVhNDVmMWM0YzEzMjk0ZDc5NzliYw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- Y2I2YTc2MjA0OTQ1MmFhMDEyZjBmNTZkY2IwMjVjNTg0MzQ1NzY4ZGRlYzIx
10
- ZjY4OTAxNzRhMGVjYjU3OTMxYjg1YzVhNjQ0MmQzZTIxNzQwMzAyYTM2MDFj
11
- M2ExZmFiZGU3NWRlN2U3YzBjOGE3MDNkMjJkMWQwNTAyNDViYjE=
9
+ ZjEyZGJiNGRjYzI0N2IzNjg0MDRmYWUwNTk4MDI0ZDdhMGYzMjMxMjdlNDRl
10
+ NWMzMjdiNDRhMGQ1NzQyYWI1ZmVlMTNhNmI1NTk3ZDk1MWVlZmFkNDM1MDIx
11
+ YzMxZjczYTZjYTBmYmY0YWQ4ZmZlYjExYjQyNzRhYTdkZTA2OWQ=
12
12
  data.tar.gz: !binary |-
13
- ZjJkZDk1ZjIzOTVlODQ2YWU3MWE0ZmZkMGM3NTMyMTA2ODNlZGJlOWViOTJm
14
- OTYyOTdkMTc0ODkyNTViNjI1Y2YzZDhlOGUyOWE4YzZhNzMzODlkNmQ1M2Jj
15
- YmMzODcwMWRjMjIwNGVlOTkzZWMyMTJhZjQ3NDhhZmMyNjQ0ZjA=
13
+ ZjZjMzE1NjMxYzMyZjUwZjc3YThhZjRlMzY5ZTVjYzliOGFkYjJkZWMwNWU3
14
+ MzQ3ZjZmNDM4NjdhZDY3ZTUzZGM3ZThjNGE3MTUzYjU0ZjQ2YmMxMjhhOGUy
15
+ MmJkOTNhZDdlMjhiYjEyZmM5ODY5NWVkNDVjNThmNjhmNzZhMDE=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oddb2xml (2.0.7)
4
+ oddb2xml (2.0.8)
5
5
  archive-tar-minitar (~> 0.5.2)
6
6
  mechanize (~> 2.5.1)
7
7
  nokogiri (~> 1.5.10)
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ === 2.0.8 / 29.04.2015
2
+
3
+ * --calc.
4
+ ** Fixed adding substances instead of a way too long label_description, eg. 7680616310019 Moviprep Orange, Pulver
5
+ ** emit EXCIPIENS for each composition
6
+
1
7
  === 2.0.7 / 29.04.2015
2
8
 
3
9
  * parse swissmedic composition with the help of RubyGem parslet.
@@ -712,6 +712,7 @@ module Oddb2xml
712
712
  xml.COMPOSITIONS {
713
713
  info.compositions.each { |composition|
714
714
  xml.COMPOSITION {
715
+ xml.EXCIPIENS { emit_substance(xml, composition.excipiens) } if composition.excipiens
715
716
  xml.CORRESP composition.corresp if composition.corresp
716
717
  xml.LABEL composition.label if composition.label
717
718
  xml.LABEL_DESCRIPTION composition.label_description if composition.label_description
@@ -296,8 +296,7 @@ class CompositionParser < Parslet::Parser
296
296
  }
297
297
 
298
298
  rule(:excipiens) { substance_lead.maybe.as(:more_info) >> space? >>
299
- ( excipiens_dose | excipiens_identifiers.as(:excipiens_description)) >>
300
- space? >> excipiens_dose.maybe.as(:dose_2) >>
299
+ ( excipiens_dose | (excipiens_identifiers >> any.repeat(0)).as(:excipiens_description)) >>
301
300
  any.repeat(0)
302
301
  }
303
302
 
@@ -419,14 +418,17 @@ class CompositionParser < Parslet::Parser
419
418
 
420
419
  rule(:polvac) { label_id.as(:label) >> label_separator >> space? >> composition.as(:composition) >> space? >> str('.').maybe >> space? }
421
420
 
422
- rule(:label_composition) { label >> space? >> composition.as(:excipiens) >> space? >> str('.').maybe >> space? }
423
421
  rule(:label_comment_excipiens) { label >> space? >> excipiens.as(:excipiens) >> space? >> str('.').maybe >> space? }
424
422
 
423
+ rule(:label_id_composition) { label_id.as(:label) >> label_separator >>
424
+ ((space >> identifier).repeat(1) >> str(':')).maybe.as(:label_description) >>
425
+ composition.as(:composition) }
426
+
425
427
  rule(:expression_comp) {
428
+ multiple_et_line |
429
+ label_id_composition |
426
430
  corresp_line_neu |
427
431
  leading_label.maybe >> space? >> composition.as(:composition) >> space? >> str('.').maybe >> space? |
428
- multiple_et_line |
429
- label_composition |
430
432
  polvac |
431
433
  label_comment_excipiens |
432
434
  excipiens.as(:composition) |
@@ -10,7 +10,7 @@ require 'parslet'
10
10
  require 'parslet/convenience'
11
11
  require 'oddb2xml/compositions_syntax'
12
12
  include Parslet
13
- VERBOSE_MESSAGES = false
13
+ VERBOSE_MESSAGES ||= false
14
14
 
15
15
  module ParseUtil
16
16
  # this class is responsible to patch errors in swissmedic entries after
@@ -51,7 +51,7 @@ module ParseUtil
51
51
  result = result.gsub(entry.pattern, entry.replacement)
52
52
  unless result.eql?(intermediate)
53
53
  entry.nr_occurrences += 1
54
- puts "#{File.basename(__FILE__)}:#{__LINE__}: fixed \nbefore: #{intermediate}\nafter: #{result}"
54
+ puts "#{File.basename(__FILE__)}:#{__LINE__}: fixed \nbefore: #{intermediate}\nafter: #{result}" unless defined?(RSpec)
55
55
  end
56
56
  }
57
57
  @nrLines += 1
@@ -156,12 +156,17 @@ class CompositionTransformer < Parslet::Transform
156
156
  |dictionary|
157
157
  puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
158
158
  info = dictionary[:excipiens].is_a?(Hash) ? dictionary[:excipiens] : dictionary[:excipiens].first
159
- @@excipiens = ParseSubstance.new(info[:excipiens_description] ? info[:excipiens_description] : 'Excipiens')
160
- @@excipiens.dose = info[:dose] if info[:dose]
161
- @@excipiens.more_info = CompositionTransformer.get_ratio(dictionary)
162
- @@excipiens.cdose = info[:dose_corresp] if info[:dose_corresp]
163
- @@excipiens.more_info = info[:more_info] if info[:more_info]
164
- binding.pry if dictionary[:dose_2]
159
+ if info[:excipiens_description] or
160
+ info[:dose] or
161
+ info[:dose_corresp] or
162
+ info[:more_info] or
163
+ CompositionTransformer.get_ratio(dictionary)
164
+ @@excipiens = ParseSubstance.new(info[:excipiens_description] ? info[:excipiens_description] : 'Excipiens')
165
+ @@excipiens.dose = info[:dose] if info[:dose]
166
+ @@excipiens.more_info = CompositionTransformer.get_ratio(dictionary)
167
+ @@excipiens.cdose = info[:dose_corresp] if info[:dose_corresp]
168
+ @@excipiens.more_info = info[:more_info] if info[:more_info]
169
+ end
165
170
  nil
166
171
  }
167
172
  rule(:composition => subtree(:composition),
@@ -416,7 +421,7 @@ class ParseComposition
416
421
  if label and not /((A|B|C|D|E|I|II|III|IV|\)+)\s+et\s+(A|B|C|D|E|I|II|III|IV|\))+)/.match(label)
417
422
  result.label = label
418
423
  end
419
- result.label_description = label_description
424
+ result.label_description = label_description.gsub(/:+$/, '').strip if label_description
420
425
  end
421
426
  return result
422
427
  end
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "2.0.7"
2
+ VERSION = "2.0.8"
3
3
  end
data/spec/calc_spec.rb CHANGED
@@ -343,6 +343,10 @@ if RunAllTests
343
343
  XPath.match( doc, "//ARTICLE[GTIN='7680611860045']/NAME").first.text.should eq 'Nutriflex Omega special, Infusionsemulsion 2500 ml'
344
344
  XPath.match( doc, "//ARTICLE[GTIN='7680611860045']/SELLING_UNITS").first.text.should eq '5'
345
345
 
346
+ XPath.match( doc, "//ARTICLE[GTIN='7680165980114']/COMPOSITIONS/COMPOSITION/EXCIPIENS/SUBSTANCE_NAME").first.text.should eq 'Excipiens ad solutionem'
347
+ XPath.match( doc, "//ARTICLE[GTIN='7680165980114']/COMPOSITIONS/COMPOSITION/EXCIPIENS/QTY").first.text.should eq '1'
348
+ XPath.match( doc, "//ARTICLE[GTIN='7680165980114']/COMPOSITIONS/COMPOSITION/EXCIPIENS/UNIT").first.text.should eq 'ml'
349
+ XPath.match( doc, "//ARTICLE[GTIN='7680165980114']/NAME").first.text.should eq 'W-Tropfen'
346
350
  end
347
351
  end
348
352
 
@@ -9,7 +9,7 @@ RunAllParsingExamples = false # Takes over 3 minutes to run, all the other ones
9
9
  GoIntoPry = true
10
10
  NoGoIntoPry = false
11
11
 
12
- if GoIntoPry
12
+ if NoGoIntoPry
13
13
 
14
14
  describe CompositionParser do
15
15
  let(:parser) { CompositionParser.new }
@@ -28,29 +28,14 @@ let(:parser) { CompositionParser.new }
28
28
  it "parses identifier" do
29
29
  res1 = substance_parser.parse_with_debug('pollinis allergeni extractum (alnus glutinosa, betula alba, corylus avellana) 300 U.: excipiens ad solutionem pro 1 ml')
30
30
  pp res1
31
- binding.pry
32
- res1 = excipiens_parser.parse_with_debug "excipiens ad emulsionem pro 1 g"
33
- pp res1
34
- binding.pry
35
- res1 = substance_parser.parse_with_debug "excipiens ad emulsionem pro 1 g"
36
- pp res1
37
- binding.pry
38
- res2 = substance_parser.parse_with_debug "excipiens ad solutionem pro 1 ml corresp. 50 µg pro dosi"
39
- pp res2
40
- binding.pry
41
- res1 = substance_name_parser.parse_with_debug("argenti nitras aquos. D13")
42
-
43
- string =
44
- "chlorhexidini digluconas 1 mg, aromatica, color.: corresp. ethanolum 8.5 % V/V, E 127, excipiens ad solutionem pro 1 ml"
45
- res2 = composition_parser.parse_with_debug(string)
46
- res2 = substance_parser.parse_with_debug(string)
47
- pp res1
31
+ # binding.pry
48
32
  end
49
33
  end
50
34
  end
51
35
  else
52
36
 
53
37
  excipiens_tests = {
38
+ 'aqua ad iniectabilia ad solutionem pro 4 ml' => nil,
54
39
  'aether q.s. ad solutionem pro 1 g' => 'aether q.s. ad solutionem',
55
40
  'saccharum ad globulos pro 1 g' => 'saccarum',
56
41
  'q.s. ad solutionem pro 5 ml' => 'q.s. ad solutionem pro 5 ml',
@@ -71,8 +56,6 @@ excipiens_tests = {
71
56
  }
72
57
 
73
58
  substance_tests = {
74
- 'pollinis allergeni extractum (alnus glutinosa, betula alba, corylus avellana) 300 U.: excipiens ad solutionem pro 1 ml' => 'zzz',
75
- 'pollinis allergeni extractum (alnus glutinosa, betula alba, corylus avellana)' => 'xxx',
76
59
  "U = Histamin Equivalent Prick" => 'U = Histamin Equivalent Prick', # 58566
77
60
  "Vipera aspis > 1000 LD50 mus et Vipera berus > 500 LD50, natrii chloridum" => "Vipera Aspis > 1000 Ld50 Mus",
78
61
  "Vipera aspis > 1000 LD50 mus et Vipera berus > 500 LD50, natrii chloridum, polysorbatum 80" => "Vipera Aspis > 1000 Ld50 Mus",
@@ -80,7 +63,6 @@ substance_tests = {
80
63
  "Vipera aspis > 1000 LD50 mus et Vipera berus > 500 LD50, natrii chloridum, polysorbatum 80, aqua ad iniectabilia q.s. ad solutionem pro 4 ml" => "Vipera Aspis > 1000 Ld50 Mus",
81
64
  "antitoxinum equis Fab'" => "Antitoxinum Equis Fab'",
82
65
  "antitoxinum equis Fab'x" => "Antitoxinum Equis Fab'x",
83
- "aqua ad iniectabilia ad solutionem pro 4 ml" => nil,# "Aqua Ad Iniectabilia Ad Solutionem Pro",
84
66
  "calcii gluconas 100 mg corresp. calcium 100 mg" => 'Calcii Gluconas',
85
67
  "calcii gluconas 100 mg et calcii lactas pentahydricus 25 mg et calcii hydrogenophosphas anhydricus 300 mg corresp. calcium 100 mg" => 'Calcii Gluconas',
86
68
  "calcii gluconas 100 mg et calcii lactas pentahydricus 25 mg et calcii hydrogenophosphas anhydricus 300 mg" => 'Calcii Gluconas',
@@ -93,8 +75,6 @@ substance_tests = {
93
75
  "conserv.: E 217, E 219, natrii dehydroacetas" => "E 217",
94
76
  "conserv.: E 217, E 219, natrii dehydroacetas, excipiens ad solutionem pro 1 ml corresp. 50 µg pro dosi" => "line #{__LINE__}",
95
77
  "ethanolum 59.5 % V/V" => 'Ethanolum',
96
- "excipiens ad solutionem pro 1 ml corresp. 50 µg pro dosi" => "Excipiens Ad Solutionem Pro 1 Ml Corresp. 50 µg Pro Dosi",
97
- "excipiens ad solutionem pro 1 ml corresp. 50 µg pro dosi" => "line #{__LINE__}",
98
78
  "globulina equina (immunisé')" => "Globulina Equina (immunisé')",
99
79
  "globulina equina (immunisé)" => 'Globulina Equina (immunisé)',
100
80
  "globulina equina'" => "Globulina Equina'",
@@ -124,7 +104,6 @@ substance_tests = {
124
104
  'benzoe 40 ml' => 'Benzoe',
125
105
  'color.: E 160(a)' => 'E 160', # TODO: or E 160(a) ??
126
106
  'ethanolum 70-78 % V/V' => "Ethanolum",
127
- 'excipiens ad solutionem pro 1 ml' => "Ad Solutionem Pro",
128
107
  'ginseng extractum corresp. ginsenosidea 3.4 mg' => 'Ginseng Extractum Corresp. Ginsenosidea',
129
108
  'moelle épinière' => 'Moelle épinière',
130
109
  'pimpinellae radix 15 % ad pulverem' => 'Pimpinellae Radix',
@@ -172,8 +151,6 @@ composition_tests = [
172
151
  "color.: E 160(a)\n",
173
152
  "conserv.: E 217, E 219, natrii dehydroacetas",
174
153
  "conserv.: E 217, E 219, natrii dehydroacetas, excipiens ad solutionem pro 1 ml corresp. 50 µg pro dosi.",
175
- "excipiens ad emulsionem pro 1 g.\n",
176
- "excipiens ad solutionem pro 1 ml corresp. 50 µg pro dosi.",
177
154
  "extractum ethanolicum et glycerolicum liquidum ex absinthii herba 0.7 mg, cinnamomi cortex 3.8 mg, guaiaci lignum 14.3 mg, millefolii herba 7 mg, rhoeados flos 11 mg, tormentillae rhizoma 9.5 mg, balsamum tolutanum 0.3 mg, benzoe tonkinensis 4.8 mg, myrrha 2.4 mg, olibanum 0.9 mg, excipiens ad solutionem pro 1 ml, corresp. 40 guttae, corresp. ethanolum 37 % V/V",
178
155
  "hamamelis virginiana D1 0,22 mg, hepar sulfuris D6 2,2 mg hypericum perforatum D2 0,66 mg, mercurius solubilis hahnemanni D8 1,1 mg, symphytum officinale D6 2,2 mg, aqua ad iniectabilia, natrii chloridum q.s. ad solutionem pro 2,2 ml.\n",
179
156
  "hepar sulfuris D6 2,2 mg hypericum perforatum D2 0,66 mg",
@@ -188,7 +165,6 @@ composition_tests = [
188
165
  "sennae folium 75 % corresp. hydroxyanthracenae 2.7 %",
189
166
  "viperis antitoxinum equis F(ab')2 corresp. Vipera aspis > 1000 LD50 mus et Vipera berus > 500 LD50 mus et Vipera ammodytes > 1000 LD50 mus, natrii chloridum, polysorbatum 80, aqua ad iniectabilia q.s. ad solutionem pro 4 ml.",
190
167
  "xylometazolini hydrochloridum 0.5 mg, natrii hyaluronas, conserv.: E 217, E 219, natrii dehydroacetas, excipiens ad solutionem pro 1 ml corresp. 50 µg pro dosi.",
191
- 'excipiens ad pulverem corresp. suspensio reconstituta 1 ml',
192
168
  'gasum inhalationis, pro vitro',
193
169
  'toxoidum pertussis 25 µg et haemagglutininum filamentosum 25 µg',
194
170
  'xenonum 74 -740 MBq',
data/spec/parslet_spec.rb CHANGED
@@ -5,18 +5,18 @@ require 'pry'
5
5
  rescue LoadError
6
6
  end
7
7
  require 'pp'
8
+ VERBOSE_MESSAGES = false
8
9
  require 'spec_helper'
9
10
  require "#{Dir.pwd}/lib/oddb2xml/parslet_compositions"
10
11
  require 'parslet/rig/rspec'
11
12
 
12
13
  hostname = Socket.gethostbyname(Socket.gethostname).first
13
- RunAllCompositionsTests = /travis|localhost/i.match(hostname) != nil # takes about five minutes to run!
14
+ RunAllCompositionsTests = false # /travis|localhost/i.match(hostname) != nil # takes about five minutes to run!
14
15
  puts "hostname is #{hostname} RunAllCompositionsTests #{RunAllCompositionsTests}"
15
16
  # Testing whether 8937 composition lines can be parsed. Found 380 errors in 293 seconds
16
17
  # 520 examples, 20 failures, 1 pending
17
18
 
18
19
  RunFailingSpec = true
19
- VERBOSE_MESSAGES = true
20
20
 
21
21
  describe ParseComposition do
22
22
  to_add = %(
@@ -44,6 +44,43 @@ end
44
44
  end
45
45
 
46
46
  describe ParseComposition do
47
+ context "should handle excipiens" do
48
+ string = "conserv.: E 216, E 218, excipiens pro suppositorio."
49
+ composition = ParseComposition.from_string(string)
50
+ specify { expect( composition.substances.size).to eq 2 }
51
+ specify { expect( composition.label).to eq nil }
52
+ specify { expect( composition.excipiens.name).to match /excipiens pro suppositorio/i }
53
+ specify { expect( composition.substances.first.name).to eq "E 216" }
54
+ end
55
+
56
+ context "should return label with description" do
57
+ string = "I) Glucoselösung: glucosum anhydricum 240 g ut glucosum monohydricum, calcii chloridum dihydricum 600 mg, acidum citricum monohydricum, aqua ad iniectabilia q.s. ad solutionem pro 500 ml."
58
+ composition = ParseComposition.from_string(string)
59
+ specify { expect(composition.substances.size).to eq 3 }
60
+ specify { expect(composition.label).to eq 'I' }
61
+ specify { expect(composition.label_description).to eq 'Glucoselösung' }
62
+ end
63
+
64
+ context "should handle label-description for Cyclacur" do
65
+ # 37987 1 Cyclacur, Dragées
66
+ string = "I) Weisse Dragées: estradioli valeras 2 mg, excipiens pro compresso obducto."
67
+ composition = ParseComposition.from_string(string)
68
+ specify { expect( composition.substances.size).to eq 1 }
69
+ specify { expect( composition.label).to eq 'I' }
70
+ specify { expect( composition.label_description).to eq "Weisse Dragées" }
71
+ specify { expect( composition.substances.first.name).to eq "Estradioli Valeras" }
72
+ end
73
+
74
+ context "should handle label-description for Moviprep" do
75
+ # 61631 1 Moviprep Orange, Pulver
76
+ string = "A): macrogolum 3350 100 g, natrii sulfas anhydricus 7.5 g, natrii chloridum 2.691 g, kalii chloridum 1.015 g, arom.: aspartamum et alia, excipiens ad pulverem pro charta."
77
+ composition = ParseComposition.from_string(string)
78
+ specify { expect( composition.substances.size).to eq 6 }
79
+ specify { expect( composition.label).to eq 'A' }
80
+ specify { expect( composition.label_description).to eq nil }
81
+ specify { expect( composition.substances.first.name).to eq "Macrogolum 3350" }
82
+ end
83
+
47
84
  context "should handle 'LA 2x%" do
48
85
  # 48473 1 Wala Echinacea-Mundspray, anthroposophisches Arzneimittel
49
86
  string = "echinacea pallida ex herba LA 20% TM 10 g"
@@ -1332,19 +1369,6 @@ describe ParseUtil::HandleSwissmedicErrors do
1332
1369
  specify { expect(handler.report[1].index(replacement).class).to eq Fixnum }
1333
1370
  end
1334
1371
 
1335
- context 'should be used when calling ParseComposition' do
1336
- replacement = '\1, \2'
1337
- test_string = 'sulfuris D6 2,2 mg hypericum perforatum D2 0,66'
1338
- report = ParseComposition.reset
1339
- composition = ParseComposition.from_string(test_string).clone
1340
- report = ParseComposition.report
1341
- specify { expect(composition.substances.size).to eq 2 }
1342
- specify { expect(composition.substances.first.name).to eq 'Sulfuris D6' }
1343
- specify { expect(composition.substances.last.name).to eq 'Hypericum Perforatum D2' }
1344
- specify { expect(/report/i.match(report[0]).class).to eq MatchData }
1345
- specify { expect(report[1].index(replacement).class).to eq Fixnum }
1346
- end
1347
-
1348
1372
  end
1349
1373
  end
1350
1374
 
data/test_options.rb CHANGED
@@ -48,6 +48,7 @@ prepare_for_gem_test
48
48
  # we will skip some long running tests as travis jobs must finish in less than 50 minutes
49
49
  # unfortunately it returns a very common name
50
50
  unless 'localhost.localdomain'.eql?(Socket.gethostbyname(Socket.gethostname).first)
51
+ test_one_call('oddb2xml --calc')
51
52
  test_one_call('oddb2xml -e')
52
53
  test_one_call('oddb2xml -e -I80')
53
54
  test_one_call('oddb2xml -f dat --append -I 80')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oddb2xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7
4
+ version: 2.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yasuhiro Asaka, Zeno R.R. Davatz