lingo 1.8.1 → 1.8.2

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.
Files changed (99) hide show
  1. data/ChangeLog +23 -5
  2. data/README +1 -1
  3. data/Rakefile +5 -7
  4. data/TODO +2 -0
  5. data/bin/lingo +5 -1
  6. data/de.lang +1 -1
  7. data/en/lingo-syn.txt +0 -0
  8. data/en.lang +2 -1
  9. data/lib/lingo/attendee/abbreviator.rb +8 -9
  10. data/lib/lingo/attendee/debugger.rb +5 -4
  11. data/lib/lingo/attendee/decomposer.rb +8 -3
  12. data/lib/lingo/attendee/dehyphenizer.rb +19 -63
  13. data/lib/lingo/attendee/formatter.rb +1 -1
  14. data/lib/lingo/attendee/multi_worder.rb +67 -155
  15. data/lib/lingo/attendee/noneword_filter.rb +16 -9
  16. data/lib/lingo/attendee/object_filter.rb +1 -1
  17. data/lib/lingo/attendee/sequencer.rb +32 -63
  18. data/lib/lingo/attendee/stemmer/porter.rb +343 -0
  19. data/{info/gpl-hdr.txt → lib/lingo/attendee/stemmer.rb} +33 -0
  20. data/lib/lingo/attendee/synonymer.rb +10 -9
  21. data/lib/lingo/attendee/text_reader.rb +102 -76
  22. data/lib/lingo/attendee/text_writer.rb +23 -26
  23. data/lib/lingo/attendee/tokenizer.rb +13 -27
  24. data/lib/lingo/attendee/variator.rb +26 -66
  25. data/lib/lingo/attendee/vector_filter.rb +42 -43
  26. data/lib/lingo/attendee/word_searcher.rb +6 -7
  27. data/lib/lingo/attendee.rb +25 -7
  28. data/lib/lingo/buffered_attendee.rb +36 -10
  29. data/lib/lingo/cachable.rb +8 -8
  30. data/lib/lingo/config.rb +5 -6
  31. data/lib/lingo/ctl.rb +2 -3
  32. data/lib/lingo/database/crypter.rb +9 -26
  33. data/lib/lingo/database/gdbm_store.rb +3 -5
  34. data/lib/lingo/database/libcdb_store.rb +4 -6
  35. data/lib/lingo/database/sdbm_store.rb +11 -6
  36. data/lib/lingo/database/show_progress.rb +3 -43
  37. data/lib/lingo/database/source/key_value.rb +2 -6
  38. data/lib/lingo/database/source/multi_key.rb +3 -5
  39. data/lib/lingo/database/source/multi_value.rb +2 -6
  40. data/lib/lingo/database/source/single_word.rb +4 -6
  41. data/lib/lingo/database/source/word_class.rb +4 -10
  42. data/lib/lingo/database/source.rb +20 -18
  43. data/lib/lingo/database.rb +84 -59
  44. data/lib/lingo/error.rb +57 -1
  45. data/lib/lingo/language/dictionary.rb +21 -18
  46. data/lib/lingo/language/grammar.rb +40 -49
  47. data/lib/lingo/language/lexical.rb +6 -6
  48. data/lib/lingo/language/lexical_hash.rb +6 -0
  49. data/lib/lingo/language/word.rb +32 -15
  50. data/lib/lingo/language/word_form.rb +1 -1
  51. data/lib/lingo/language.rb +14 -25
  52. data/lib/lingo/reportable.rb +12 -10
  53. data/lib/lingo/show_progress.rb +81 -0
  54. data/lib/lingo/version.rb +1 -1
  55. data/lib/lingo.rb +63 -24
  56. data/lingo-call.cfg +6 -10
  57. data/lingo.cfg +60 -44
  58. data/lir.cfg +42 -41
  59. data/test/attendee/ts_abbreviator.rb +3 -5
  60. data/test/attendee/ts_decomposer.rb +3 -5
  61. data/test/attendee/ts_multi_worder.rb +87 -145
  62. data/test/attendee/ts_noneword_filter.rb +5 -3
  63. data/test/attendee/ts_object_filter.rb +5 -3
  64. data/test/attendee/ts_sequencer.rb +3 -5
  65. data/test/attendee/ts_stemmer.rb +309 -0
  66. data/test/attendee/ts_synonymer.rb +15 -11
  67. data/test/attendee/ts_text_reader.rb +12 -15
  68. data/test/attendee/ts_text_writer.rb +24 -29
  69. data/test/attendee/ts_tokenizer.rb +9 -7
  70. data/test/attendee/ts_variator.rb +4 -4
  71. data/test/attendee/ts_vector_filter.rb +24 -16
  72. data/test/attendee/ts_word_searcher.rb +20 -36
  73. data/test/{lir.csv → lir.vec} +0 -0
  74. data/test/ref/artikel.vec +943 -943
  75. data/test/ref/artikel.ven +943 -943
  76. data/test/ref/lir.non +201 -201
  77. data/test/ref/lir.seq +178 -178
  78. data/test/ref/lir.syn +49 -49
  79. data/test/ref/lir.vec +329 -0
  80. data/test/test_helper.rb +20 -36
  81. data/test/ts_database.rb +10 -10
  82. data/test/ts_language.rb +279 -319
  83. metadata +93 -104
  84. data/info/Objekte.png +0 -0
  85. data/info/Typen.png +0 -0
  86. data/info/database.png +0 -0
  87. data/info/db_small.png +0 -0
  88. data/info/download.png +0 -0
  89. data/info/kerze.png +0 -0
  90. data/info/language.png +0 -0
  91. data/info/lingo.png +0 -0
  92. data/info/logo.png +0 -0
  93. data/info/meeting.png +0 -0
  94. data/info/types.png +0 -0
  95. data/lingo-all.cfg +0 -89
  96. data/porter/stem.cfg +0 -311
  97. data/porter/stem.rb +0 -150
  98. data/test/ref/lir.csv +0 -329
  99. data/test.cfg +0 -79
@@ -38,17 +38,15 @@ class Lingo
38
38
 
39
39
  def initialize(id, lingo)
40
40
  super
41
-
42
- @wc = @config.fetch('def-wc', 's').downcase
43
- @mul_wc = @config.fetch('def-mul-wc', @wc).downcase
44
-
45
- @line_pattern = %r{^(#{@legal_word})$}
41
+ @pat = /^(#{@wrd})$/
42
+ @def = @config.fetch('def-wc', 's').downcase
43
+ @mul = @config.fetch('def-mul-wc', @def).downcase
46
44
  end
47
45
 
48
46
  private
49
47
 
50
48
  def convert_line(line, key, val)
51
- [key = key.strip, %W[##{key =~ /\s/ ? @mul_wc : @wc}]]
49
+ [key = key.strip, %W[##{key =~ /\s/ ? @mul : @def}]]
52
50
  end
53
51
 
54
52
  end
@@ -38,21 +38,15 @@ class Lingo
38
38
 
39
39
  def initialize(id, lingo)
40
40
  super
41
-
42
- @separator = @config.fetch('separator', ',')
43
- @line_pattern = Regexp.new('^(' + @legal_word + ')' + Regexp.escape(@separator) + '((?:' + @legal_word + '#\w)+)$')
41
+ @pat = /^(#{@wrd})#{Regexp.escape(@sep ||= ',')}((?:#{@wrd}#\w)+)$/
44
42
  end
45
43
 
46
44
  private
47
45
 
48
46
  def convert_line(line, key, val)
49
- key, valstr = key.strip, val.strip
50
- val = valstr.gsub(/\s+#/, '#').scan(/\S.+?\s*#\w/)
51
- val = val.map do |str|
52
- str =~ /^(.+)#(.)/
53
- ($1 == key ? '' : $1) + '#' + $2
54
- end
55
- [key, val]
47
+ [key = key.strip, val.strip.scan(/(\S.+?)\s*#(\w)/).map! { |v, c|
48
+ "#{v unless key == v}##{c}"
49
+ }]
56
50
  end
57
51
 
58
52
  end
@@ -63,52 +63,54 @@ class Lingo
63
63
  UTF8_CHAR = "#{UTF8_DIGIT}|#{UTF8_BASLAT}|#{UTF8_LAT1SP}|#{UTF8_LATEXA}|#{UTF8_LATEXB}|#{UTF8_IPAEXT}"
64
64
 
65
65
  PRINTABLE_CHAR = "#{UTF8_CHAR}|[<>-]"
66
+ LEGAL_CHAR = '[ /&()\[\].,-]'
66
67
 
67
68
  def self.get(name, *args)
68
- const_get(name.camelcase).new(*args)
69
+ Lingo.get_const(name, self).new(*args)
69
70
  end
70
71
 
71
- attr_reader :position
72
+ attr_reader :pos
72
73
 
73
74
  def initialize(id, lingo)
74
75
  @config = lingo.database_config(id)
75
76
 
76
- source_file = Lingo.find(:dict, name = @config['name'])
77
+ source_file = Lingo.find(:dict, name = @config['name'], relax: true)
78
+
77
79
  reject_file = begin
78
80
  Lingo.find(:store, source_file) << '.rev'
79
- rescue NoWritableStoreError
81
+ rescue NoWritableStoreError, SourceFileNotFoundError
80
82
  end
81
83
 
82
- @pn_source = Pathname.new(source_file)
83
- @pn_reject = Pathname.new(reject_file) if reject_file
84
+ @src = Pathname.new(source_file)
85
+ @rej = Pathname.new(reject_file) if reject_file
84
86
 
85
- raise SourceFileNotFoundError.new(name, id) unless @pn_source.exist?
87
+ raise SourceFileNotFoundError.new(name, id) unless @src.exist?
86
88
 
87
- @wordclass = @config.fetch('def-wc', '?').downcase
88
- @separator = @config['separator']
89
+ @def = @config.fetch('def-wc', Language::LA_UNKNOWN).downcase
90
+ @sep = @config['separator']
89
91
 
90
- @legal_word = '(?:' + PRINTABLE_CHAR + '|[' + Regexp.escape('- /&()[].,') + '])+' # TODO: v1.60 - ',' bei Source zulassen; in const.rb einbauen
91
- @line_pattern = Regexp.new('^'+@legal_word+'$')
92
+ @wrd = "(?:#{PRINTABLE_CHAR}|#{LEGAL_CHAR})+"
93
+ @pat = /^#{@wrd}$/
92
94
 
93
- @position = 0
95
+ @pos = 0
94
96
  end
95
97
 
96
98
  def size
97
- @pn_source.size
99
+ @src.size
98
100
  end
99
101
 
100
102
  def each
101
- reject_file = @pn_reject.open('w', encoding: ENC) if @pn_reject
103
+ reject_file = @rej.open('w', encoding: ENC) if @rej
102
104
 
103
- @pn_source.each_line($/, encoding: ENC) { |line|
104
- @position += length = line.bytesize
105
+ @src.each_line($/, encoding: ENC) { |line|
106
+ @pos += length = line.bytesize
105
107
 
106
108
  next if line =~ /\A\s*#/ || line.strip.empty?
107
109
 
108
110
  line.chomp!
109
111
  line.downcase!
110
112
 
111
- if length < 4096 && line =~ @line_pattern
113
+ if length < 4096 && line =~ @pat
112
114
  yield convert_line(line, $1, $2)
113
115
  else
114
116
  reject_file.puts(line) if reject_file
@@ -119,7 +121,7 @@ class Lingo
119
121
  ensure
120
122
  if reject_file
121
123
  reject_file.close
122
- @pn_reject.delete if @pn_reject.size == 0
124
+ @rej.delete if @rej.size == 0
123
125
  end
124
126
  end
125
127
 
@@ -24,17 +24,9 @@
24
24
  ###############################################################################
25
25
  #++
26
26
 
27
- require 'pathname'
28
- require 'fileutils'
29
- require 'digest/sha1'
30
-
31
27
  require_relative 'database/show_progress'
32
28
  require_relative 'database/crypter'
33
29
  require_relative 'database/source'
34
- require_relative 'database/hash_store'
35
- require_relative 'database/sdbm_store'
36
- require_relative 'database/gdbm_store'
37
- require_relative 'database/libcdb_store'
38
30
 
39
31
  class Lingo
40
32
 
@@ -49,45 +41,57 @@ class Lingo
49
41
 
50
42
  include Cachable
51
43
 
52
- BACKENDS = %w[LibCDB SDBM GDBM].unshift(ENV['LINGO_BACKEND']).compact.uniq
53
-
54
44
  FLD_SEP = '|'
55
45
  IDX_REF = '^'
56
46
  KEY_REF = '*'
57
47
  SYS_KEY = '~'
58
48
 
59
- INDEX_PATTERN = %r{\A#{Regexp.escape(IDX_REF)}\d+\z}
49
+ IDX_REF_ESC = Regexp.escape(IDX_REF)
50
+ KEY_REF_ESC = Regexp.escape(KEY_REF)
51
+
52
+ INDEX_PATTERN = %r{\A#{IDX_REF_ESC}\d+\z}
53
+
54
+ BACKENDS = []
55
+ BACKEND_BY_EXT = {}
56
+
57
+ class << self
58
+
59
+ def register(klass, ext, prio = -1, meth = true)
60
+ BACKENDS.insert(prio, name = klass.name[/::(\w+)Store\z/, 1])
61
+ Array(ext).each { |i| BACKEND_BY_EXT[i.prepend('.')] = name }
62
+
63
+ klass.const_set(:EXT, ext)
64
+ klass.class_eval('def store_ext; EXT; end', __FILE__, __LINE__) if meth
65
+ end
66
+
67
+ def open(*args, &block)
68
+ new(*args).open(&block)
69
+ end
60
70
 
61
- def self.open(*args, &block)
62
- new(*args).open(&block)
63
71
  end
64
72
 
73
+ attr_reader :backend
74
+
65
75
  def initialize(id, lingo)
66
- @config = lingo.database_config(id)
76
+ @id, @lingo, @config, @db = id, lingo, lingo.database_config(id), nil
67
77
 
68
- @id, @lingo = id, lingo
69
- @src_file = Lingo.find(:dict, @config['name'])
70
- @crypter = Crypter.new if @config.has_key?('crypt')
78
+ @srcfile = Lingo.find(:dict, @config['name'], relax: true)
79
+ @crypter = @config.has_key?('crypt') && Crypter.new
71
80
 
72
81
  begin
73
- @dbm_name = Lingo.find(:store, @src_file)
74
- FileUtils.mkdir_p(File.dirname(@dbm_name))
82
+ @stofile = Lingo.find(:store, @srcfile)
83
+ FileUtils.mkdir_p(File.dirname(@stofile))
84
+ rescue SourceFileNotFoundError => err
85
+ @stofile = skip_ext = err.id
86
+ backend = backend_from_file(@stofile) unless err.name
75
87
  rescue NoWritableStoreError
76
- @backend = HashStore
88
+ backend = HashStore
77
89
  end
78
90
 
79
- extend(backend)
80
-
81
- @dbm_name << store_ext if respond_to?(:store_ext, true)
82
-
91
+ use_backend(backend, skip_ext)
83
92
  init_cachable
84
- convert unless uptodate?
85
- end
86
93
 
87
- def backend
88
- @backend ||= BACKENDS.find { |mod|
89
- break self.class.const_get("#{mod}Store") if Object.const_defined?(mod)
90
- } || HashStore
94
+ convert unless uptodate?
91
95
  end
92
96
 
93
97
  def closed?
@@ -97,6 +101,8 @@ class Lingo
97
101
  def open
98
102
  @db = _open if closed?
99
103
  block_given? ? yield(self) : self
104
+ rescue => err
105
+ raise DatabaseError.new(:open, @stofile, err)
100
106
  ensure
101
107
  close if @db && block_given?
102
108
  end
@@ -134,16 +140,36 @@ class Lingo
134
140
  val.uniq!
135
141
  store(key, val)
136
142
 
137
- val = val.join(FLD_SEP)
138
- key, val = @crypter.encode(key, val) if @crypter
139
-
140
- _set(key, val)
143
+ arg = [key, val.join(FLD_SEP)]
144
+ _set(*@crypter ? @crypter.encode(*arg) : arg)
141
145
  end
142
146
 
143
147
  private
144
148
 
145
- def uptodate?(file = @dbm_name)
146
- src = Pathname.new(@src_file)
149
+ def use_backend(backend = nil, skip_ext = false)
150
+ [ENV['LINGO_BACKEND'], *BACKENDS].each { |mod|
151
+ backend = get_backend(mod) and break if mod
152
+ } unless backend
153
+
154
+ extend(@backend = backend || HashStore)
155
+
156
+ @stofile << store_ext if !skip_ext && respond_to?(:store_ext)
157
+ end
158
+
159
+ def get_backend(mod)
160
+ self.class.const_get("#{mod}Store") if Object.const_defined?(mod)
161
+ rescue TypeError, NameError
162
+ end
163
+
164
+ def backend_from_file(file)
165
+ ext = File.extname(file)
166
+
167
+ mod = BACKEND_BY_EXT[ext] or raise BackendNotFoundError.new(file)
168
+ get_backend(mod) or raise BackendNotAvailableError.new(mod, file)
169
+ end
170
+
171
+ def uptodate?(file = @stofile)
172
+ src = Pathname.new(@srcfile)
147
173
  @source_key = lambda { [src.size, src.mtime].join(FLD_SEP) }
148
174
 
149
175
  sys_key = open { @db[SYS_KEY] } if File.exist?(file)
@@ -160,7 +186,7 @@ class Lingo
160
186
  end
161
187
 
162
188
  def _clear
163
- File.delete(@dbm_name) if File.exist?(@dbm_name)
189
+ File.delete(@stofile) if File.exist?(@stofile)
164
190
  end
165
191
 
166
192
  def _open
@@ -186,42 +212,35 @@ class Lingo
186
212
  end
187
213
  end
188
214
 
215
+ def warn(*msg)
216
+ @lingo.warn(*msg)
217
+ end
218
+
189
219
  def convert(verbose = @lingo.config.stderr.tty?)
190
- src = Source.get(@config.fetch('txt-format', 'KeyValue'), @id, @lingo)
220
+ src = Source.get(@config.fetch('txt-format', 'key_value'), @id, @lingo)
191
221
 
192
222
  if lex = @config['use-lex']
193
- a, s = [{
194
- 'source' => lex.split(STRING_SEPARATOR_RE),
195
- 'mode' => @config['lex-mode']
196
- }, @lingo], ' '
197
-
198
- dic = Language::Dictionary.new(*a)
199
- gra = Language::Grammar.new(*a)
200
-
201
- block = lambda { |form|
202
- res = dic.find_word(form)
203
-
204
- if res.unknown?
205
- res = gra.find_compositum(form)
206
- com = res.compo_form
207
- end
223
+ a = [{ 'source' => lex.split(SEP_RE), 'mode' => @config['lex-mode'] }, @lingo]
224
+ d, g = Language::Dictionary.new(*a), Language::Grammar.new(*a); a = nil
208
225
 
209
- com ? com.form : res.norm
226
+ sep, block = ' ', lambda { |f|
227
+ (r = d.find_word(f)).unknown? &&
228
+ (c = (r = g.find_compound(f)).compo_form) ? c.form : r.norm
210
229
  }
211
230
  end
212
231
 
213
232
  ShowProgress.new(self, src.size, verbose) { |progress| create {
214
233
  src.each { |key, val|
215
- progress[src.position]
234
+ progress[src.pos]
216
235
 
217
236
  if key
218
237
  key.chomp!('.')
219
238
 
220
- if lex && key.include?(s)
221
- k = key.split(s).map!(&block).join(s)
239
+ if lex && key.include?(sep)
240
+ k = key.split(sep).map!(&block).join(sep)
222
241
 
223
- c = k.count(s) + 1
224
- self[k.split(s)[0, 3].join(s)] = ["#{KEY_REF}#{c}"] if c > 3
242
+ c = k.count(sep) + 1
243
+ self[k.split(sep)[0, 3].join(sep)] = ["#{KEY_REF}#{c}"] if c > 3
225
244
 
226
245
  key, val = k, val.map { |v| v.start_with?('#') ? key + v : v }
227
246
  end
@@ -237,3 +256,9 @@ class Lingo
237
256
  end
238
257
 
239
258
  end
259
+
260
+ # in order of priority
261
+ require_relative 'database/libcdb_store'
262
+ require_relative 'database/sdbm_store'
263
+ require_relative 'database/gdbm_store'
264
+ require_relative 'database/hash_store'
data/lib/lingo/error.rb CHANGED
@@ -37,7 +37,49 @@ class Lingo
37
37
  end
38
38
 
39
39
  def to_s
40
- 'No writable store found in search path'
40
+ 'No writable store found in search path.'
41
+ end
42
+
43
+ end
44
+
45
+ class BackendNotFoundError < LingoError
46
+
47
+ attr_reader :file
48
+
49
+ def initialize(file)
50
+ @file = file
51
+ end
52
+
53
+ def to_s
54
+ "No backend found for `#{file}'."
55
+ end
56
+
57
+ end
58
+
59
+ class BackendNotAvailableError < LingoError
60
+
61
+ attr_reader :mod, :file
62
+
63
+ def initialize(mod, file)
64
+ @mod, @file = mod, file
65
+ end
66
+
67
+ def to_s
68
+ "Backend not available `#{mod}' for `#{file}'."
69
+ end
70
+
71
+ end
72
+
73
+ class DatabaseError < LingoError
74
+
75
+ attr_reader :action, :file, :err
76
+
77
+ def initialize(action, file, err)
78
+ @action, @file, @err = action, file, err
79
+ end
80
+
81
+ def to_s
82
+ "An error occured when trying to #{action} `#{file}': #{err} (#{err.class})"
41
83
  end
42
84
 
43
85
  end
@@ -119,4 +161,18 @@ class Lingo
119
161
 
120
162
  end
121
163
 
164
+ class NameNotFoundError < LingoError
165
+
166
+ attr_reader :klass, :name
167
+
168
+ def initialize(klass, name)
169
+ @klass, @name = klass, name
170
+ end
171
+
172
+ def to_s
173
+ "No such #{klass.name.split('::').last} type `#{name}'."
174
+ end
175
+
176
+ end
177
+
122
178
  end
@@ -33,6 +33,12 @@ class Lingo
33
33
  include Cachable
34
34
  include Reportable
35
35
 
36
+ def self.open(*args)
37
+ yield dictionary = new(*args)
38
+ ensure
39
+ dictionary.close if dictionary
40
+ end
41
+
36
42
  def initialize(config, lingo)
37
43
  unless config.has_key?('source')
38
44
  raise ArgumentError, 'Required parameter `source\' missing.'
@@ -43,32 +49,29 @@ class Lingo
43
49
 
44
50
  @suffixes, @infixes = [], []
45
51
 
46
- if suffix = lingo.dictionary_config['suffix']
47
- suffix.each { |t, s|
48
- t.downcase!
52
+ Array(lingo.dictionary_config['suffix']).each { |t, s|
53
+ t.downcase!
49
54
 
50
- s.split.each { |suf|
51
- su, ex = suf.split('/')
55
+ a = t == 'f' ? @infixes : @suffixes
52
56
 
53
- (t == 'f' ? @infixes : @suffixes) << [
54
- Regexp.new(su << '$', 'i'), ex || '*', t
55
- ]
56
- }
57
+ s.split.each { |r|
58
+ f, e = r.split('/')
59
+ a << [/#{f}$/i, e || '*', t]
57
60
  }
58
- end
61
+ }
59
62
 
60
- @sources = config['source'].map { |src| lingo.lexical_hash(src) }
61
- @all_sources = config['mode'].nil? || config['mode'].downcase == 'all'
63
+ @src = config['source'].map { |src| lingo.lexical_hash(src) }
64
+ @all = config['mode'].nil? || config['mode'].downcase == 'all'
62
65
 
63
66
  lingo.dictionaries << self
64
67
  end
65
68
 
66
69
  def close
67
- @sources.each(&:close)
70
+ @src.each(&:close)
68
71
  end
69
72
 
70
73
  def report
71
- super.tap { |rep| @sources.each { |src| rep.update(src.report) } }
74
+ super.tap { |rep| @src.each { |src| rep.update(src.report) } }
72
75
  end
73
76
 
74
77
  # _dic_.find_word( _aString_ ) -> _aNewWord_
@@ -95,11 +98,11 @@ class Lingo
95
98
  lex = [obj] if lex.empty? && obj.unknown?
96
99
 
97
100
  # multiworder optimization
98
- ref = %r{\A#{Regexp.escape(Database::KEY_REF)}\d+}o
101
+ ref = %r{\A#{Database::KEY_REF_ESC}\d+}
99
102
 
100
103
  lex.each_with_object([]) { |l, s|
101
104
  next if l.attr == LA_SYNONYM
102
- next if l.attr != LA_KOMPOSITUM && obj.attr == WA_KOMPOSITUM
105
+ next if l.attr != LA_COMPOUND && obj.attr == WA_COMPOUND
103
106
 
104
107
  select(l.form).each { |y| s << y unless y =~ ref }
105
108
  }
@@ -109,10 +112,10 @@ class Lingo
109
112
  #
110
113
  # Sucht alle Wörterbücher durch und gibt den ersten Treffer zurück (+mode = first+), oder alle Treffer (+mode = all+)
111
114
  def select(str)
112
- @sources.each_with_object([]) { |src, lex|
115
+ @src.each_with_object([]) { |src, lex|
113
116
  l = src[str] or next
114
117
  lex.concat(l)
115
- break lex unless @all_sources
118
+ break lex unless @all
116
119
  }.tap { |lex| lex.sort!; lex.uniq! }
117
120
  end
118
121