Class: Lingo

Inherits:
Object
  • Object
show all
Defined in:
lib/lingo/call.rb,
lib/lingo.rb,
lib/lingo/ctl.rb,
lib/lingo/app.rb,
lib/lingo/web.rb,
lib/lingo/cli.rb,
lib/lingo/srv.rb,
lib/lingo/debug.rb,
lib/lingo/error.rb,
lib/lingo/config.rb,
lib/lingo/filter.rb,
lib/lingo/version.rb,
lib/lingo/progress.rb,
lib/lingo/database.rb,
lib/lingo/attendee.rb,
lib/lingo/language.rb,
lib/lingo/ctl/other.rb,
lib/lingo/ctl/files.rb,
lib/lingo/filter/xml.rb,
lib/lingo/filter/pdf.rb,
lib/lingo/text_utils.rb,
lib/lingo/ctl/analysis.rb,
lib/lingo/language/char.rb,
lib/lingo/language/word.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/deferred_attendee.rb,
lib/lingo/buffered_attendee.rb,
lib/lingo/attendee/debugger.rb,
lib/lingo/attendee/variator.rb,
lib/lingo/attendee/tokenizer.rb,
lib/lingo/language/word_form.rb,
lib/lingo/attendee/sequencer.rb,
lib/lingo/attendee/formatter.rb,
lib/lingo/attendee/synonymer.rb,
lib/lingo/database/hash_store.rb,
lib/lingo/attendee/hal_filter.rb,
lib/lingo/attendee/lsi_filter.rb,
lib/lingo/database/gdbm_store.rb,
lib/lingo/attendee/decomposer.rb,
lib/lingo/language/dictionary.rb,
lib/lingo/database/sdbm_store.rb,
lib/lingo/attendee/text_writer.rb,
lib/lingo/attendee/text_reader.rb,
lib/lingo/attendee/abbreviator.rb,
lib/lingo/attendee/multi_worder.rb,
lib/lingo/attendee/debug_filter.rb,
lib/lingo/database/libcdb_store.rb,
lib/lingo/language/lexical_hash.rb,
lib/lingo/attendee/word_searcher.rb,
lib/lingo/attendee/object_filter.rb,
lib/lingo/attendee/vector_filter.rb,
lib/lingo/attendee/stemmer/porter.rb,
lib/lingo/attendee/analysis_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, TextUtils, Version Classes: App, Attendee, BackendNotAvailableError, BackendNotFoundError, BufferedAttendee, CLI, Call, Config, ConfigError, ConfigLoadError, Database, DatabaseError, DeferredAttendee, FileNotFoundError, Filter, 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



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

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

  @config_args = args
  reset(false)
end

Instance Attribute Details

#dictionariesObject (readonly)

Returns the value of attribute dictionaries



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

def dictionaries
  @dictionaries
end

Class Method Details

.append_path(*path) ⇒ Object



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

def append_path(*path)
  include_path(path)
end

.basename(type, file) ⇒ Object



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

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

.basepath(type, file) ⇒ Object



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

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

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



75
76
77
# File 'lib/lingo.rb', line 75

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

.ctlObject



144
145
146
147
148
149
# File 'lib/lingo/ctl.rb', line 144

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

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



95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/lingo.rb', line 95

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



127
128
129
130
131
# File 'lib/lingo.rb', line 127

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

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



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/lingo.rb', line 79

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



123
124
125
# File 'lib/lingo.rb', line 123

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

.talk(*args) ⇒ Object



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

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

Instance Method Details

#configObject



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

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

#database_config(id) ⇒ Object



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

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



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

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

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



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 268

def invite(list = config['meeting/attendees'])
  supplier, subscriber = Hash.array, Hash.array

  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.subscribers.concat(subscriber[ch])
  } }
end

#lexical_hash(src) ⇒ Object



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

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.nest { |k| Language::LexicalHash.new(k, self) }
end

#startObject



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

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

#talkObject



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

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