oddb2xml 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/Gemfile.lock +1 -1
- data/History.txt +13 -0
- data/dokumentation_calc.textile +30 -24
- data/lib/oddb2xml/builder.rb +32 -19
- data/lib/oddb2xml/calc.rb +10 -1
- data/lib/oddb2xml/compositions_syntax.rb +220 -151
- data/lib/oddb2xml/parslet_compositions.rb +148 -323
- data/lib/oddb2xml/version.rb +1 -1
- data/spec/calc_spec.rb +19 -13
- data/spec/composition_syntax_spec.rb +39 -40
- data/spec/data/swissmedic_package-galenic.xlsx +0 -0
- data/spec/parslet_spec.rb +320 -213
- data/spec/spec_helper.rb +0 -1
- metadata +2 -2
@@ -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 "
|
54
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: fixed \nbefore: #{intermediate}\nafter: #{result}"
|
55
55
|
end
|
56
56
|
}
|
57
57
|
@nrLines += 1
|
@@ -93,6 +93,122 @@ class QtyLit < Struct.new(:qty)
|
|
93
93
|
end
|
94
94
|
|
95
95
|
class CompositionTransformer < Parslet::Transform
|
96
|
+
def CompositionTransformer.get_ratio(parse_info)
|
97
|
+
if parse_info[:ratio]
|
98
|
+
if parse_info[:ratio].to_s.length > 0 and parse_info[:ratio].to_s != ', '
|
99
|
+
parse_info[:ratio].to_s.sub(/^,\s+/, '').sub(/,\s+$/,'')
|
100
|
+
else
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
else
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
rule(:corresp => simple(:corresp),
|
109
|
+
) {
|
110
|
+
|dictionary|
|
111
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
112
|
+
@@corresp = dictionary[:corresp].to_s
|
113
|
+
}
|
114
|
+
rule( :substance_name => simple(:substance_name),
|
115
|
+
:dose => simple(:dose),
|
116
|
+
) {
|
117
|
+
|dictionary|
|
118
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
119
|
+
dose = dictionary[:dose].is_a?(ParseDose) ? dictionary[:dose] : nil
|
120
|
+
substance = ParseSubstance.new(dictionary[:substance_name], dose)
|
121
|
+
@@substances << substance
|
122
|
+
substance
|
123
|
+
}
|
124
|
+
|
125
|
+
rule( :more_info => simple(:more_info),
|
126
|
+
) {
|
127
|
+
|dictionary|
|
128
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
129
|
+
@@corresp = dictionary[:more_info].to_s.strip.sub(/:$/, '')
|
130
|
+
}
|
131
|
+
rule( :more_info => simple(:more_info),
|
132
|
+
:substance_name => simple(:substance_name),
|
133
|
+
:dose => simple(:dose),
|
134
|
+
) {
|
135
|
+
|dictionary|
|
136
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
137
|
+
dose = dictionary[:dose].is_a?(ParseDose) ? dictionary[:dose] : nil
|
138
|
+
substance = ParseSubstance.new(dictionary[:substance_name].to_s, dose)
|
139
|
+
substance.more_info = dictionary[:more_info].to_s.strip.sub(/:$/, '') if dictionary[:more_info] and dictionary[:more_info].to_s.length > 0
|
140
|
+
@@substances << substance
|
141
|
+
substance
|
142
|
+
}
|
143
|
+
|
144
|
+
rule(:lebensmittel_zusatz => simple(:lebensmittel_zusatz),
|
145
|
+
:more_info => simple(:more_info),
|
146
|
+
:digits => simple(:digits)) {
|
147
|
+
|dictionary|
|
148
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
149
|
+
substance = ParseSubstance.new("#{dictionary[:lebensmittel_zusatz]} #{dictionary[:digits]}")
|
150
|
+
substance.more_info = dictionary[:more_info].to_s.sub(/:\s+$/, '').strip if dictionary[:more_info]
|
151
|
+
@@substances << substance
|
152
|
+
substance
|
153
|
+
}
|
154
|
+
rule(:excipiens => subtree(:excipiens),
|
155
|
+
) {
|
156
|
+
|dictionary|
|
157
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
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]
|
165
|
+
nil
|
166
|
+
}
|
167
|
+
rule(:composition => subtree(:composition),
|
168
|
+
) {
|
169
|
+
|dictionary|
|
170
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
171
|
+
info = dictionary[:composition].is_a?(Hash) ? dictionary[:composition] : dictionary[:composition].first
|
172
|
+
if info.is_a?(Hash)
|
173
|
+
@@excipiens = ParseSubstance.new(info[:excipiens_description] ? info[:excipiens_description] : 'Excipiens')
|
174
|
+
@@excipiens.dose = info[:dose] if info[:dose]
|
175
|
+
@@excipiens.more_info = CompositionTransformer.get_ratio(dictionary)
|
176
|
+
@@excipiens.cdose = info[:dose_corresp] if info[:dose_corresp]
|
177
|
+
@@excipiens.more_info = info[:more_info] if info[:more_info]
|
178
|
+
binding.pry if dictionary[:dose_2]
|
179
|
+
@@excipiens
|
180
|
+
else
|
181
|
+
info
|
182
|
+
end
|
183
|
+
}
|
184
|
+
rule(:substance => simple(:substance),
|
185
|
+
:chemical_substance => simple(:chemical_substance),
|
186
|
+
:substance_ut => sequence(:substance_ut),
|
187
|
+
:ratio => simple(:ratio),
|
188
|
+
) {
|
189
|
+
|dictionary|
|
190
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
191
|
+
ratio = CompositionTransformer.get_ratio(dictionary)
|
192
|
+
if ratio and ratio.length > 0
|
193
|
+
if dictionary[:substance].more_info
|
194
|
+
dictionary[:substance].more_info += ' ' + ratio.strip
|
195
|
+
else
|
196
|
+
dictionary[:substance].more_info = ratio.strip
|
197
|
+
end
|
198
|
+
end
|
199
|
+
if dictionary[:chemical_substance]
|
200
|
+
dictionary[:substance].chemical_substance = dictionary[:chemical_substance]
|
201
|
+
@@substances -= [dictionary[:chemical_substance]]
|
202
|
+
end
|
203
|
+
if dictionary[:substance_ut].size > 0
|
204
|
+
dictionary[:substance].salts += dictionary[:substance_ut].last.salts
|
205
|
+
dictionary[:substance_ut].last.salts = []
|
206
|
+
dictionary[:substance].salts << dictionary[:substance_ut].last
|
207
|
+
@@substances -= dictionary[:substance_ut]
|
208
|
+
end
|
209
|
+
dictionary[:substance]
|
210
|
+
}
|
211
|
+
|
96
212
|
rule(:int => simple(:int)) { IntLit.new(int) }
|
97
213
|
rule(:number => simple(:nb)) {
|
98
214
|
nb.match(/[eE\.]/) ? Float(nb) : Integer(nb)
|
@@ -115,8 +231,17 @@ class CompositionTransformer < Parslet::Transform
|
|
115
231
|
:unit => simple(:unit)) { ParseDose.new(nil, unit) }
|
116
232
|
rule(
|
117
233
|
:qty => simple(:qty)) { ParseDose.new(qty, nil) }
|
234
|
+
rule(
|
235
|
+
:qty => simple(:qty),
|
236
|
+
:unit => simple(:unit),
|
237
|
+
:dose_right => simple(:dose_right),
|
238
|
+
) {
|
239
|
+
dose = ParseDose.new(qty, unit)
|
240
|
+
dose.unit = dose.unit.to_s + ' et ' + ParseDose.new(dose_right).to_s
|
241
|
+
dose
|
242
|
+
}
|
118
243
|
|
119
|
-
|
244
|
+
@@substances ||= []
|
120
245
|
@@excipiens = nil
|
121
246
|
def CompositionTransformer.clear_substances
|
122
247
|
@@substances = []
|
@@ -132,311 +257,6 @@ class CompositionTransformer < Parslet::Transform
|
|
132
257
|
def CompositionTransformer.corresp
|
133
258
|
@@corresp ? @@corresp.clone : nil
|
134
259
|
end
|
135
|
-
|
136
|
-
rule(:ratio => simple(:ratio) ) {
|
137
|
-
|dictionary|
|
138
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
139
|
-
@@substances.last.more_info = dictionary[:ratio].to_s if @@substances.last
|
140
|
-
}
|
141
|
-
rule(:substance => sequence(:substance),
|
142
|
-
:ratio => simple(:ratio)) {
|
143
|
-
|dictionary|
|
144
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
145
|
-
@@substances.last.more_info = dictionary[:ratio].to_s if @@substances.last
|
146
|
-
}
|
147
|
-
|
148
|
-
rule(:solvens => simple(:solvens) ) {
|
149
|
-
|dictionary|
|
150
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
151
|
-
substance = ParseSubstance.new(dictionary[:solvens].to_s)
|
152
|
-
substance.more_info = 'Solvens'
|
153
|
-
@@substances << substance
|
154
|
-
}
|
155
|
-
rule(:lebensmittel_zusatz => simple(:lebensmittel_zusatz),
|
156
|
-
:more_info => simple(:more_info),
|
157
|
-
:digits => simple(:digits)) {
|
158
|
-
|dictionary|
|
159
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
160
|
-
substance = ParseSubstance.new("#{dictionary[:lebensmittel_zusatz]} #{dictionary[:digits]}")
|
161
|
-
substance.more_info = dictionary[:more_info].to_s.sub(/:$/, '')
|
162
|
-
@@substances << substance
|
163
|
-
}
|
164
|
-
rule(:lebensmittel_zusatz => simple(:lebensmittel_zusatz),
|
165
|
-
:digits => simple(:digits)) {
|
166
|
-
|dictionary|
|
167
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
168
|
-
@@substances << ParseSubstance.new("#{dictionary[:lebensmittel_zusatz]} #{dictionary[:digits]}")
|
169
|
-
dictionary[:substance]
|
170
|
-
}
|
171
|
-
rule(:substance => simple(:substance)) {
|
172
|
-
|dictionary|
|
173
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
174
|
-
}
|
175
|
-
rule(:substance_name => simple(:substance_name),
|
176
|
-
:dose => simple(:dose),
|
177
|
-
) {
|
178
|
-
|dictionary|
|
179
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
180
|
-
@@substances << ParseSubstance.new(dictionary[:substance_name].to_s, dictionary[:dose])
|
181
|
-
}
|
182
|
-
rule(:substance_ut => sequence(:substance_ut),
|
183
|
-
) {
|
184
|
-
|dictionary|
|
185
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
186
|
-
nil
|
187
|
-
}
|
188
|
-
rule(:for_ut => sequence(:for_ut),
|
189
|
-
) {
|
190
|
-
|dictionary|
|
191
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
192
|
-
if dictionary[:for_ut].size > 1
|
193
|
-
@@substances[-2].salts << dictionary[:for_ut].last.clone
|
194
|
-
@@substances.delete(dictionary[:for_ut].last)
|
195
|
-
end
|
196
|
-
nil
|
197
|
-
}
|
198
|
-
|
199
|
-
rule(:substance_name => simple(:substance_name),
|
200
|
-
:dose => simple(:dose),
|
201
|
-
:substance_corresp => sequence(:substance_corresp),
|
202
|
-
) {
|
203
|
-
|dictionary|
|
204
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
205
|
-
substance = ParseSubstance.new(dictionary[:substance_name].to_s, dictionary[:dose])
|
206
|
-
substance.chemical_substance = @@substances.last
|
207
|
-
@@substances.delete_at(-1)
|
208
|
-
@@substances << substance
|
209
|
-
}
|
210
|
-
|
211
|
-
rule(:mineralia => simple(:mineralia),
|
212
|
-
:more_info => simple(:more_info),
|
213
|
-
:substance_name => simple(:substance_name),
|
214
|
-
:dose => simple(:dose),
|
215
|
-
) {
|
216
|
-
|dictionary|
|
217
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
218
|
-
substance = ParseSubstance.new(dictionary[:substance_name].to_s, dictionary[:dose])
|
219
|
-
substance.more_info = dictionary[:mineralia].to_s + ' ' + dictionary[:more_info].to_s
|
220
|
-
# TODO: fix alia
|
221
|
-
@@substances << substance
|
222
|
-
}
|
223
|
-
rule(:substance_name => simple(:substance_name),
|
224
|
-
:conserv => simple(:conserv),
|
225
|
-
:dose => simple(:dose),
|
226
|
-
) {
|
227
|
-
|dictionary|
|
228
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
229
|
-
substance = ParseSubstance.new(dictionary[:substance_name], ParseDose.new(dictionary[:dose].to_s))
|
230
|
-
@@substances << substance
|
231
|
-
substance.more_info = dictionary[:conserv].to_s.sub(/:$/, '')
|
232
|
-
}
|
233
|
-
|
234
|
-
rule(:substance_name => simple(:substance_name),
|
235
|
-
:mineralia => simple(:mineralia),
|
236
|
-
) {
|
237
|
-
|dictionary|
|
238
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
239
|
-
substance = ParseSubstance.new(dictionary[:substance_name])
|
240
|
-
substance.more_info = dictionary[:mineralia].to_s.sub(/:$/, '')
|
241
|
-
@@substances << substance
|
242
|
-
}
|
243
|
-
rule(:substance_name => simple(:substance_name),
|
244
|
-
:more_info => simple(:more_info),
|
245
|
-
) {
|
246
|
-
|dictionary|
|
247
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
248
|
-
substance = ParseSubstance.new(dictionary[:substance_name])
|
249
|
-
@@substances << substance
|
250
|
-
substance.more_info = dictionary[:more_info].to_s.sub(/:$/, '')
|
251
|
-
}
|
252
|
-
rule(:substance_name => simple(:substance_name),
|
253
|
-
:residui => simple(:residui),
|
254
|
-
) {
|
255
|
-
|dictionary|
|
256
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
257
|
-
binding.pry
|
258
|
-
substance = ParseSubstance.new(dictionary[:substance_name])
|
259
|
-
@@substances << substance
|
260
|
-
substance.more_info = dictionary[:residui].to_s.sub(/:$/, '')
|
261
|
-
}
|
262
|
-
rule(:qty => simple(:qty),
|
263
|
-
:unit => simple(:unit),
|
264
|
-
:dose_right => simple(:dose_right),
|
265
|
-
) {
|
266
|
-
|dictionary|
|
267
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
268
|
-
ParseDose.new(dictionary[:qty].to_s, dictionary[:unit].to_s + ' et ' + dictionary[:dose_right].to_s )
|
269
|
-
}
|
270
|
-
|
271
|
-
rule(:substance_name => simple(:substance_name),
|
272
|
-
:qty => simple(:qty),
|
273
|
-
) {
|
274
|
-
|dictionary|
|
275
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
276
|
-
@@substances << ParseSubstance.new(dictionary[:substance_name].to_s.strip, ParseDose.new(dictionary[:qty].to_s))
|
277
|
-
}
|
278
|
-
|
279
|
-
rule(:substance_name => simple(:substance_name),
|
280
|
-
:dose_corresp => simple(:dose_corresp),
|
281
|
-
) {
|
282
|
-
|dictionary|
|
283
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
284
|
-
@@substances << ParseSubstance.new(dictionary[:substance_name].to_s, dictionary[:dose_corresp])
|
285
|
-
}
|
286
|
-
rule(:description => simple(:description),
|
287
|
-
:substance_name => simple(:substance_name),
|
288
|
-
:qty => simple(:qty),
|
289
|
-
:more_info => simple(:more_info),
|
290
|
-
) {
|
291
|
-
|dictionary|
|
292
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
293
|
-
substance = ParseSubstance.new(dictionary[:substance_name], ParseDose.new(dictionary[:qty].to_s))
|
294
|
-
@@substances << substance
|
295
|
-
substance.more_info = dictionary[:more_info].to_s
|
296
|
-
substance.description = dictionary[:description].to_s
|
297
|
-
substance
|
298
|
-
}
|
299
|
-
rule(:der => simple(:der),
|
300
|
-
) {
|
301
|
-
|dictionary|
|
302
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
303
|
-
@@substances << ParseSubstance.new(dictionary[:der].to_s)
|
304
|
-
}
|
305
|
-
rule(:der => simple(:der),
|
306
|
-
:substance_corresp => sequence(:substance_corresp),
|
307
|
-
) {
|
308
|
-
|dictionary|
|
309
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
310
|
-
substance = ParseSubstance.new(dictionary[:der].to_s)
|
311
|
-
substance.chemical_substance = @@substances.last
|
312
|
-
@@substances.delete_at(-1)
|
313
|
-
@@substances << substance
|
314
|
-
}
|
315
|
-
rule(:histamin => simple(:histamin),
|
316
|
-
) {
|
317
|
-
|dictionary|
|
318
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: histamin dictionary #{dictionary}"
|
319
|
-
@@substances << ParseSubstance.new(dictionary[:histamin].to_s)
|
320
|
-
}
|
321
|
-
rule(:substance_name => simple(:substance_name),
|
322
|
-
) {
|
323
|
-
|dictionary|
|
324
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
325
|
-
@@substances << ParseSubstance.new(dictionary[:substance_name].to_s)
|
326
|
-
}
|
327
|
-
rule(:one_substance => sequence(:one_substance)) {
|
328
|
-
|dictionary|
|
329
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
330
|
-
@@substances << ParseSubstance.new(dictionary[:one_substance])
|
331
|
-
}
|
332
|
-
rule(:one_substance => sequence(:one_substance)) {
|
333
|
-
|dictionary|
|
334
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
335
|
-
@@substances << ParseSubstance.new(dictionary[:one_substance])
|
336
|
-
}
|
337
|
-
|
338
|
-
rule(:substance_name => simple(:substance_name),
|
339
|
-
:substance_ut => sequence(:substance_ut),
|
340
|
-
:dose => simple(:dose),
|
341
|
-
) {
|
342
|
-
|dictionary|
|
343
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
344
|
-
@@substances.last.salts << ParseSubstance.new(dictionary[:substance_name].to_s, dictionary[:dose])
|
345
|
-
nil
|
346
|
-
}
|
347
|
-
|
348
|
-
rule(:mineralia => simple(:mineralia),
|
349
|
-
:dose => simple(:dose),
|
350
|
-
:substance_name => simple(:substance_name),
|
351
|
-
) {
|
352
|
-
|dictionary|
|
353
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
354
|
-
dose = dictionary[:dose].is_a?(ParseDose) ? dictionary[:dose] : ParseDose.new(dictionary[:dose].to_s)
|
355
|
-
substance = ParseSubstance.new(dictionary[:substance_name], dose)
|
356
|
-
substance.more_info = dictionary[:mineralia].to_s
|
357
|
-
@@substances << substance
|
358
|
-
# @@substances << ParseSubstance.new(dictionary[:substance_name].to_s, dictionary[:dose])
|
359
|
-
}
|
360
|
-
|
361
|
-
rule(:mineralia => simple(:mineralia),
|
362
|
-
:dose => simple(:dose),
|
363
|
-
:substance_ut => simple(:substance_ut),
|
364
|
-
) {
|
365
|
-
|dictionary|
|
366
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
367
|
-
dose = dictionary[:dose].is_a?(ParseDose) ? dictionary[:dose] : ParseDose.new(dictionary[:dose].to_s)
|
368
|
-
substance = ParseSubstance.new(dictionary[:substance_ut], dose)
|
369
|
-
substance.more_info = dictionary[:mineralia].to_s
|
370
|
-
binding.pry
|
371
|
-
@@substances << substance
|
372
|
-
nil
|
373
|
-
}
|
374
|
-
|
375
|
-
|
376
|
-
rule(:mineralia => simple(:mineralia),
|
377
|
-
:substance_ut => simple(:substance_ut),
|
378
|
-
) {
|
379
|
-
|dictionary|
|
380
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}"
|
381
|
-
binding.pry
|
382
|
-
@@substances.last.salts << ParseSubstance.new(dictionary[:substance_name].to_s, dictionary[:dose])
|
383
|
-
nil
|
384
|
-
}
|
385
|
-
rule( :more_info => simple(:more_info),
|
386
|
-
:substance_name => simple(:substance_name),
|
387
|
-
:dose => simple(:dose),
|
388
|
-
) {
|
389
|
-
|dictionary|
|
390
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
391
|
-
dose = dictionary[:dose].is_a?(ParseDose) ? dictionary[:dose] : ParseDose.new(dictionary[:dose].to_s)
|
392
|
-
substance = ParseSubstance.new(dictionary[:substance_name], dose)
|
393
|
-
substance.more_info = dictionary[:more_info].to_s
|
394
|
-
@@substances << substance
|
395
|
-
}
|
396
|
-
|
397
|
-
rule(:excipiens => simple(:excipiens),
|
398
|
-
) {
|
399
|
-
|dictionary|
|
400
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
401
|
-
@@excipiens = dictionary[:excipiens].is_a?(ParseDose) ? ParseSubstance.new('excipiens', dictionary[:excipiens]) : nil
|
402
|
-
}
|
403
|
-
|
404
|
-
rule(:substance_name => simple(:substance_name),
|
405
|
-
:dose_pro => simple(:dose_pro),
|
406
|
-
) {
|
407
|
-
|dictionary|
|
408
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
409
|
-
dose = dictionary[:dose_pro].is_a?(ParseDose) ? dictionary[:dose_pro] : ParseDose.new(dictionary[:dose_pro].to_s)
|
410
|
-
substance = ParseSubstance.new(dictionary[:substance_name], dose)
|
411
|
-
@@excipiens = dose
|
412
|
-
@@substances << substance
|
413
|
-
}
|
414
|
-
rule(:substance_name => simple(:substance_name),
|
415
|
-
:dose => simple(:dose),
|
416
|
-
:dose_pro => simple(:dose_pro),
|
417
|
-
) {
|
418
|
-
|dictionary|
|
419
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
420
|
-
dose = dictionary[:dose_pro].is_a?(ParseDose) ? dictionary[:dose_pro] : ParseDose.new(dictionary[:dose_pro].to_s)
|
421
|
-
dose_pro = dictionary[:dose_pro].is_a?(ParseDose) ? dictionary[:dose_pro] : ParseDose.new(dictionary[:dose_pro].to_s)
|
422
|
-
substance = ParseSubstance.new(dictionary[:substance_name], dose)
|
423
|
-
@@excipiens = dose_pro
|
424
|
-
@@substances << substance
|
425
|
-
}
|
426
|
-
|
427
|
-
rule(:dose_pro => simple(:dose_pro),
|
428
|
-
) {
|
429
|
-
|dictionary|
|
430
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
431
|
-
dictionary[:dose_pro]
|
432
|
-
}
|
433
|
-
|
434
|
-
rule(:corresp => simple(:corresp),
|
435
|
-
) {
|
436
|
-
|dictionary|
|
437
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
438
|
-
@@corresp = dictionary[:corresp].to_s
|
439
|
-
}
|
440
260
|
end
|
441
261
|
|
442
262
|
class ParseDose
|
@@ -509,15 +329,21 @@ end
|
|
509
329
|
|
510
330
|
class ParseComposition
|
511
331
|
attr_accessor :source, :label, :label_description, :substances, :galenic_form, :route_of_administration,
|
512
|
-
:corresp
|
332
|
+
:corresp, :excipiens
|
513
333
|
|
514
|
-
ErrorsToFix = { /(
|
515
|
-
/(\d+)\s+\-\s*(\d+)/ => '\1-\2',
|
334
|
+
ErrorsToFix = { /(\d+)\s+\-\s*(\d+)/ => '\1-\2',
|
516
335
|
'o.1' => '0.1',
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
336
|
+
/\s+(mg|g) DER:/ => ' \1, DER:',
|
337
|
+
' mind. ' => ' min. ',
|
338
|
+
' streptococci pyogen. ' => ' streptococci pyogen ',
|
339
|
+
' ut excipiens' => ', excipiens',
|
340
|
+
' Corresp. ' => ' corresp. ',
|
341
|
+
',,' => ',',
|
342
|
+
'avena elatior,dactylis glomerata' => 'avena elatior, dactylis glomerata',
|
343
|
+
' color.: corresp. ' => ' corresp.',
|
344
|
+
/ U\.: (excipiens) / => ' U. \1 ',
|
345
|
+
/ U\.: (alnus|betula|betula|betulae) / => ' U., \1 ',
|
346
|
+
/^(acari allergeni extractum (\(acarus siro\)|).+\s+U\.\:)/ => 'A): \1',
|
521
347
|
}
|
522
348
|
@@errorHandler = ParseUtil::HandleSwissmedicErrors.new( ErrorsToFix )
|
523
349
|
|
@@ -536,7 +362,6 @@ class ParseComposition
|
|
536
362
|
return nil if string == nil or string.eql?('.') or string.eql?('')
|
537
363
|
stripped = string.gsub(/^"|["\n]+$/, '')
|
538
364
|
return nil unless stripped
|
539
|
-
@@errorHandler.nrParsingErrors += 1
|
540
365
|
if /(U\.I\.|U\.)$/.match(stripped)
|
541
366
|
cleaned = stripped
|
542
367
|
else
|
@@ -547,7 +372,6 @@ class ParseComposition
|
|
547
372
|
|
548
373
|
cleaned = @@errorHandler.apply_fixes(cleaned)
|
549
374
|
puts "ParseComposition.new cleaned #{cleaned}" if VERBOSE_MESSAGES and not cleaned.eql?(stripped)
|
550
|
-
|
551
375
|
CompositionTransformer.clear_substances
|
552
376
|
result = ParseComposition.new(cleaned)
|
553
377
|
parser3 = CompositionParser.new
|
@@ -555,28 +379,30 @@ class ParseComposition
|
|
555
379
|
begin
|
556
380
|
if defined?(RSpec)
|
557
381
|
ast = transf3.apply(parser3.parse_with_debug(cleaned))
|
558
|
-
puts "#{File.basename(__FILE__)}:#{__LINE__}: ==>
|
382
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: ==> " if VERBOSE_MESSAGES
|
383
|
+
pp ast if VERBOSE_MESSAGES
|
559
384
|
else
|
560
385
|
ast = transf3.apply(parser3.parse(cleaned))
|
561
386
|
end
|
562
387
|
rescue Parslet::ParseFailed => error
|
388
|
+
@@errorHandler.nrParsingErrors += 1
|
563
389
|
puts "#{File.basename(__FILE__)}:#{__LINE__}: failed parsing ==> #{cleaned}"
|
564
390
|
return nil
|
565
391
|
end
|
566
392
|
result.source = string
|
567
393
|
return result unless ast
|
568
394
|
return result if ast.is_a?(Parslet::Slice)
|
569
|
-
# pp ast; binding.pry
|
570
395
|
|
571
396
|
result.substances = CompositionTransformer.substances
|
572
|
-
excipiens = CompositionTransformer.excipiens
|
397
|
+
result.excipiens = CompositionTransformer.excipiens
|
573
398
|
result.corresp = CompositionTransformer.corresp if CompositionTransformer.corresp
|
574
|
-
if excipiens and excipiens.unit
|
575
|
-
pro_qty = "/#{excipiens.qty} #{excipiens.unit}".sub(/\/1\s+/, '/')
|
399
|
+
if result.excipiens and result.excipiens.unit
|
400
|
+
pro_qty = "/#{result.excipiens.qty} #{result.excipiens.unit}".sub(/\/1\s+/, '/')
|
576
401
|
result.substances.each {
|
577
402
|
|substance|
|
403
|
+
next unless substance.is_a?(ParseSubstance)
|
578
404
|
substance.chemical_substance.unit = "#{substance.chemical_substance.unit}#{pro_qty}" if substance.chemical_substance
|
579
|
-
substance.dose.unit = "#{substance.dose.unit}#{pro_qty}" if substance.unit and not substance.unit.eql?(excipiens.unit)
|
405
|
+
substance.dose.unit = "#{substance.dose.unit}#{pro_qty}" if substance.unit and not substance.unit.eql?(result.excipiens.unit)
|
580
406
|
}
|
581
407
|
end
|
582
408
|
if ast.is_a?(Array) and ast.first.is_a?(Hash)
|
@@ -592,7 +418,6 @@ class ParseComposition
|
|
592
418
|
end
|
593
419
|
result.label_description = label_description
|
594
420
|
end
|
595
|
-
@@errorHandler.nrParsingErrors -=1 if result.substances.size > 0 or result.corresp
|
596
421
|
return result
|
597
422
|
end
|
598
423
|
end
|
data/lib/oddb2xml/version.rb
CHANGED
data/spec/calc_spec.rb
CHANGED
@@ -293,7 +293,7 @@ if RunAllTests
|
|
293
293
|
m = />.* /.match(xml)
|
294
294
|
m.should eq nil
|
295
295
|
doc = REXML::Document.new xml
|
296
|
-
#
|
296
|
+
# puts xml; binding.pry
|
297
297
|
gtin = '7680540151009'
|
298
298
|
ean12 = '7680' + sprintf('%05d',tst_naropin.iksnr_A) + sprintf('%03d',tst_naropin.pack_K)
|
299
299
|
ean13 = (ean12 + Oddb2xml.calc_checksum(ean12))
|
@@ -328,14 +328,20 @@ if RunAllTests
|
|
328
328
|
|
329
329
|
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/SUBSTANCE_NAME").
|
330
330
|
find{|x| x.text.eql?(matri_name)}.text.should eq matri_name
|
331
|
-
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/
|
331
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/NAME").last.text.should eq 'Kamillin Medipharm, Bad'
|
332
332
|
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/QTY").first.text.should eq '98.9'
|
333
|
-
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/MORE_INFO").first.text.should eq 'ratio: 1:2-2.8'
|
334
333
|
XPath.match( doc, "//ARTICLE[GTIN='7680300150105']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/SUBSTANCE_NAME").first.text.should eq 'Lidocaini Hydrochloridum'
|
335
334
|
XPath.match( doc, "//ARTICLE[GTIN='7680300150105']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/UNIT").first.text.should eq 'mg/ml'
|
335
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/CHEMICAL_SUBSTANCE/SUBSTANCE_NAME").first.text.should eq 'Levomenolum'
|
336
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/CHEMICAL_SUBSTANCE/MORE_INFO").first.text.should eq 'ratio: 1:2-2.8'
|
337
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/CHEMICAL_SUBSTANCE/DOSE_TEXT").first.text.should eq '10-50 mg'
|
338
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/CHEMICAL_SUBSTANCE/QTY").first.should eq nil
|
339
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680434541015']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/CHEMICAL_SUBSTANCE/UNIT").first.should eq nil
|
336
340
|
|
337
|
-
XPath.match( doc, "//ARTICLE[GTIN='
|
338
|
-
|
341
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680446250592']/COMPOSITIONS/COMPOSITION/SUBSTANCES/SUBSTANCE/SALTS/SALT/SUBSTANCE_NAME").first.text.should eq 'Ceftriaxonum Natricum'
|
342
|
+
|
343
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680611860045']/NAME").first.text.should eq 'Nutriflex Omega special, Infusionsemulsion 2500 ml'
|
344
|
+
XPath.match( doc, "//ARTICLE[GTIN='7680611860045']/SELLING_UNITS").first.text.should eq '5'
|
339
345
|
|
340
346
|
end
|
341
347
|
end
|
@@ -464,14 +470,14 @@ if RunAllTests
|
|
464
470
|
specify { expect(fluticasoni.dose.to_s).to eq "100 µg/25 mg" }
|
465
471
|
lactosum = info.first.substances.find{ |x| x.name.match(/Lactosum/i) }
|
466
472
|
specify { expect(lactosum.name).to eq "Lactosum Monohydricum" }
|
467
|
-
specify { expect(lactosum.dose
|
473
|
+
specify { expect(lactosum.dose).to eq nil }
|
468
474
|
end
|
469
475
|
|
470
476
|
context 'find correct result compositions for stuff with percents' do
|
471
477
|
txt = 'calcium carbonicum hahnemanni C7 5 %, chamomilla recutita D5 22.5 %, magnesii hydrogenophosphas trihydricus C5 50 %, passiflora incarnata D5 22.5 %, xylitolum, excipiens ad globulos.'
|
472
478
|
info = ParseUtil.parse_compositions(txt)
|
473
479
|
specify { expect(info.size).to eq 1 }
|
474
|
-
specify { expect(info.first.substances.size).to eq
|
480
|
+
specify { expect(info.first.substances.size).to eq 5 }
|
475
481
|
recutita = info.first.substances.find{ |x| x.name.match(/recutita/i) }
|
476
482
|
specify { expect(recutita.name).to eq 'Chamomilla Recutita D5' }
|
477
483
|
specify { expect(recutita.qty.to_f).to eq 22.5 }
|
@@ -498,11 +504,11 @@ if RunAllTests
|
|
498
504
|
text
|
499
505
|
)
|
500
506
|
specify { expect(info.compositions.size).to eq 2 }
|
501
|
-
specify { expect(info.compositions.first.substances.size).to eq
|
507
|
+
specify { expect(info.compositions.first.substances.size).to eq 6 }
|
502
508
|
poloxamerum = info.compositions.first.substances.find{ |x| x.name.match(/poloxamerum/i) }
|
503
509
|
skip { expect(poloxamerum.name).to eq 'Poloxamerum 238' }
|
504
510
|
skip { expect(poloxamerum.qty.to_f).to eq "" }
|
505
|
-
specify { expect(poloxamerum.unit).to eq
|
511
|
+
specify { expect(poloxamerum.unit).to eq nil }
|
506
512
|
end
|
507
513
|
|
508
514
|
context 'find correct result for 61676 Phostal 3-Bäume A): ' do
|
@@ -566,7 +572,7 @@ Solvens: aqua ad iniectabilia q.s. ad suspensionem pro 1 ml."
|
|
566
572
|
text
|
567
573
|
)
|
568
574
|
specify { expect(info.compositions.size).to eq 2 }
|
569
|
-
specify { expect(info.compositions.first.label).to eq
|
575
|
+
specify { expect(info.compositions.first.label).to eq "Praeparatio cryodesiccata:" }
|
570
576
|
substance1 = info.compositions.first.substances.find{ |x| x.name.match(/virus rabiei inactivatu/i) }
|
571
577
|
specify { expect(substance1).should_not be nil }
|
572
578
|
if substance1
|
@@ -612,14 +618,14 @@ Die HILFSSTOFFE sind Aqua ad iniectabilia und Natrii chloridum.
|
|
612
618
|
text)
|
613
619
|
specify { expect(info.pkg_size).to eq '2 x 7' }
|
614
620
|
specify { expect(info.selling_units).to eq 14 }
|
615
|
-
specify { expect(info.compositions.first.substances.size).to eq
|
621
|
+
specify { expect(info.compositions.first.substances.size).to eq 2 }
|
616
622
|
viscum = info.compositions.first.substances.find{ |x| x.name.match(/viscum/i) }
|
617
623
|
specify { expect(viscum).not_to eq nil}
|
618
624
|
natrii = info.compositions.first.substances.find{ |x| x.name.match(/natrii chloridum/i) }
|
619
625
|
specify { expect(natrii).not_to eq nil}
|
620
626
|
if viscum
|
621
627
|
specify { expect(viscum.name).to eq 'Extractum Aquosum Liquidum Fermentatum 0.05 Mg Ex Viscum Album (mali) Recens' }
|
622
|
-
|
628
|
+
skip { expect(viscum.is_active_agent).to eq true } # TODO: Grenzfall. Active-Agent viscum album (mali) recens ist sub-string
|
623
629
|
specify { expect(viscum.dose.to_s).to eq '0.01 mg/ml' }
|
624
630
|
specify { expect(viscum.qty.to_f).to eq 0.01}
|
625
631
|
specify { expect(viscum.unit).to eq 'mg/ml'}
|
@@ -633,7 +639,7 @@ Die HILFSSTOFFE sind Aqua ad iniectabilia und Natrii chloridum.
|
|
633
639
|
text)
|
634
640
|
specify { expect(info.pkg_size).to eq '2 x 7' }
|
635
641
|
specify { expect(info.selling_units).to eq 14 }
|
636
|
-
specify { expect(info.compositions.first.substances.size).to eq
|
642
|
+
specify { expect(info.compositions.first.substances.size).to eq 3 }
|
637
643
|
viscum = info.compositions.first.substances.find{ |x| x.name.match(/viscum/i) }
|
638
644
|
specify { expect(viscum).not_to eq nil}
|
639
645
|
if viscum
|