Class: Lingo

Inherits:
Object
  • Object
show all
Defined in:
lib/lingo/call.rb,
lib/lingo.rb,
lib/lingo/srv.rb,
lib/lingo/cli.rb,
lib/lingo/ctl.rb,
lib/lingo/app.rb,
lib/lingo/web.rb,
lib/lingo/debug.rb,
lib/lingo/error.rb,
lib/lingo/config.rb,
lib/lingo/version.rb,
lib/lingo/language.rb,
lib/lingo/progress.rb,
lib/lingo/database.rb,
lib/lingo/attendee.rb,
lib/lingo/language/word.rb,
lib/lingo/language/char.rb,
lib/lingo/language/token.rb,
lib/lingo/database/source.rb,
lib/lingo/database/crypter.rb,
lib/lingo/language/grammar.rb,
lib/lingo/language/lexical.rb,
lib/lingo/attendee/stemmer.rb,
lib/lingo/database/progress.rb,
lib/lingo/buffered_attendee.rb,
lib/lingo/attendee/debugger.rb,
lib/lingo/attendee/variator.rb,
lib/lingo/attendee/synonymer.rb,
lib/lingo/attendee/sequencer.rb,
lib/lingo/attendee/tokenizer.rb,
lib/lingo/attendee/formatter.rb,
lib/lingo/language/word_form.rb,
lib/lingo/language/dictionary.rb,
lib/lingo/database/hash_store.rb,
lib/lingo/database/sdbm_store.rb,
lib/lingo/attendee/decomposer.rb,
lib/lingo/database/gdbm_store.rb,
lib/lingo/attendee/text_writer.rb,
lib/lingo/attendee/abbreviator.rb,
lib/lingo/attendee/text_reader.rb,
lib/lingo/language/lexical_hash.rb,
lib/lingo/attendee/multi_worder.rb,
lib/lingo/database/libcdb_store.rb,
lib/lingo/attendee/dehyphenizer.rb,
lib/lingo/attendee/vector_filter.rb,
lib/lingo/attendee/word_searcher.rb,
lib/lingo/attendee/object_filter.rb,
lib/lingo/attendee/stemmer/porter.rb,
lib/lingo/attendee/noneword_filter.rb,
lib/lingo/database/source/key_value.rb,
lib/lingo/database/source/multi_key.rb,
lib/lingo/database/source/word_class.rb,
lib/lingo/database/source/multi_value.rb,
lib/lingo/database/source/single_word.rb

Overview

#

Lingo – A full-featured automatic indexing system #

#

Copyright (C) 2005-2007 John Vorhauer # Copyright (C) 2007-2014 John Vorhauer, Jens Wille #

#

Lingo is free software; you can redistribute it and/or modify it under the # terms of the GNU Affero General Public License as published by the Free # Software Foundation; either version 3 of the License, or (at your option) # any later version. #

#

Lingo is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for # more details. #

#

You should have received a copy of the GNU Affero General Public License # along with Lingo. If not, see <www.gnu.org/licenses/>. #

#

++

Direct Known Subclasses

Call

Defined Under Namespace

Modules: Ctl, Debug, Language, Version Classes: App, Attendee, BackendNotAvailableError, BackendNotFoundError, BufferedAttendee, CLI, Call, Config, ConfigError, ConfigLoadError, Database, DatabaseError, FileNotFoundError, InvalidDatabaseConfigError, LibraryLoadError, LingoError, MissingConfigError, NameNotFoundError, NoDatabaseConfigError, NoWritableStoreError, Progress, SourceFileNotFoundError, Srv, TokenizeError, Web

Constant Summary

BASE =

The system-wide Lingo directory (LINGO_BASE).

ENV['LINGO_BASE'] || File.expand_path('../..', __FILE__)
HOME =

The user's personal Lingo directory (LINGO_HOME).

ENV['LINGO_HOME'] || File.join(ENV.user_home, '.lingo')
CURR =

The local Lingo directory (LINGO_CURR).

ENV['LINGO_CURR'] || '.'
PATH =

The search path for Lingo dictionary and configuration files.

ENV['LINGO_PATH'].nil? ? [CURR, HOME, BASE] :
ENV['LINGO_PATH'].split(File::PATH_SEPARATOR)
FIND_OPTIONS =

Map of file types to their standard location and file extension.

{
  config: { dir: 'config', ext: 'cfg'  },
  dict:   { dir: 'dict',   ext: 'txt'  },
  lang:   { dir: 'lang',   ext: 'lang' },
  store:  { dir: 'store',  ext:  nil   },
  sample: { dir: 'txt',    ext: 'txt'  }
}
SEP_RE =
%r{[; ,|]}
VERSION =
Version.to_s

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Lingo

Returns a new instance of Lingo



226
227
228
229
230
231
# File 'lib/lingo.rb', line 226

def initialize(*args)
  Debug.ps(:lingo_new)

  @config_args = args
  reset(false)
end

Instance Attribute Details

#dictionariesObject (readonly)

Returns the value of attribute dictionaries



233
234
235
# File 'lib/lingo.rb', line 233

def dictionaries
  @dictionaries
end

Class Method Details

.append_path(*path) ⇒ Object



116
117
118
# File 'lib/lingo.rb', line 116

def append_path(*path)
  include_path(path)
end

.basename(type, file) ⇒ Object



107
108
109
110
# File 'lib/lingo.rb', line 107

def basename(type, file)
  dir, name = File.split(file)
  type != :dict ? name : File.join(File.basename(dir), name)
end

.basepath(type, file) ⇒ Object



112
113
114
# File 'lib/lingo.rb', line 112

def basepath(type, file)
  File.join(options_for(type)[:dir], basename(type, file))
end

.call(cfg = find(:config, 'lingo-call'), args = [], &block) ⇒ Object



72
73
74
# File 'lib/lingo.rb', line 72

def call(cfg = find(:config, 'lingo-call'), args = [], &block)
  Call.new(['-c', cfg, *args]).call(&block)
end

.ctlObject



296
297
298
299
300
301
# File 'lib/lingo/ctl.rb', line 296

def self.ctl
  Ctl.ctl
rescue => err
  raise if $VERBOSE
  abort "#{err.backtrace.first}: #{err} (#{err.class})"
end

.find(type, file, options = {}) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/lingo.rb', line 92

def find(type, file, options = {})
  if options.is_a?(Array)
    path    = options
    options = options_for(type)
  else
    options = options_for(type, options)
    path    = path_for(options)
  end

  type = :file if type != :store
  send("find_#{type}", file, path, options)
rescue RuntimeError, Errno::ENOENT => err
  block_given? ? yield(err) : raise
end

.get_const(name, klass = self) ⇒ Object



124
125
126
127
128
# File 'lib/lingo.rb', line 124

def get_const(name, klass = self)
  klass.const_get(name.camelcase)
rescue NameError
  raise NameNotFoundError.new(klass, name)
end

.list(type, options = {}) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/lingo.rb', line 76

def list(type, options = {})
  options = options_for(type, options)

  glob, list = file_with_ext('*', options), []
  glob = File.join('??', glob) if type == :dict

  walk(path = path_for(options), options) { |dir|
    Dir[File.join(dir, glob)].sort!.each { |file|
      pn = Pathname.new(file)
      list << realpath_for(pn, path) if pn.file?
    }
  }

  list
end

.prepend_path(*path) ⇒ Object



120
121
122
# File 'lib/lingo.rb', line 120

def prepend_path(*path)
  include_path(path, true)
end

.talk(*args) ⇒ Object



68
69
70
# File 'lib/lingo.rb', line 68

def talk(*args)
  new(*args).talk
end

Instance Method Details

#configObject



235
236
237
238
239
# File 'lib/lingo.rb', line 235

def config
  @config ||= Config.new(*@config_args)
rescue => err
  raise ConfigLoadError.new(err)
end

#database_config(id) ⇒ Object



245
246
247
248
249
250
# File 'lib/lingo.rb', line 245

def database_config(id)
  dictionary_config['databases'][id].tap { |cfg|
    raise NoDatabaseConfigError.new(id) unless cfg
    raise InvalidDatabaseConfigError.new(id) unless cfg.key?('name')
  }
end

#dictionary_configObject



241
242
243
# File 'lib/lingo.rb', line 241

def dictionary_config
  @dictionary_config ||= config['language/dictionary']
end

#invite(list = config['meeting/attendees']) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/lingo.rb', line 267

def invite(list = config['meeting/attendees'])
  supplier   = Hash.new { |h, k| h[k] = [] }
  subscriber = Hash.new { |h, k| h[k] = [] }

  last_link, auto_link = '', 0

  list.each { |hash|
    name = (name_key = hash.keys.first).camelcase

    cfg = (config["language/attendees/#{name.downcase}"] || {})
      .merge(hash.values.first).update('name' => name)

    %w[in out].each { |key| (cfg[key] ||= '').downcase! }

    cfg['in']  = last_link                     if cfg['in'].empty?
    cfg['out'] = "auto_link-#{auto_link += 1}" if cfg['out'].empty?
    last_link  = cfg['out']

    @attendees << attendee = Attendee.const_get(name).new(cfg, self)

    unless name == (real = attendee.class.name.split('::').last)
      config.deprecate(name_key, real.underscore, attendee, :name)
    end

    { 'in' => subscriber, 'out' => supplier }.each { |key, target|
      cfg[key].split(SEP_RE).each { |ch| target[ch] << attendee }
    }
  }

  supplier.each { |ch, attendees| attendees.each { |att|
    att.add_subscriber(subscriber[ch])
  } }
end

#lexical_hash(src) ⇒ Object



252
253
254
# File 'lib/lingo.rb', line 252

def lexical_hash(src)
  @lexical_hash[src]
end

#reset(close = true) ⇒ Object



305
306
307
308
309
# File 'lib/lingo.rb', line 305

def reset(close = true)
  dictionaries.each { |i| i.close } if close
  @dictionaries, @attendees = [], []
  @lexical_hash = Hash.new { |h, k| h[k] = Language::LexicalHash.new(k, self) }
end

#startObject



301
302
303
# File 'lib/lingo.rb', line 301

def start
  @attendees.first.listen(:TALK)
end

#talkObject



256
257
258
259
260
261
262
263
264
265
# File 'lib/lingo.rb', line 256

def talk
  Debug.profile(config['profile']) {
    invite
    start
  }

  Debug.ps(:lingo_talk)
ensure
  reset
end

#warn(*msg) ⇒ Object



311
312
313
# File 'lib/lingo.rb', line 311

def warn(*msg)
  config.warn(*msg)
end