Class: Lingo

Inherits:
Object
  • Object
show all
Defined in:
lib/lingo/call.rb,
lib/lingo.rb,
lib/lingo/app.rb,
lib/lingo/ctl.rb,
lib/lingo/cli.rb,
lib/lingo/srv.rb,
lib/lingo/web.rb,
lib/lingo/debug.rb,
lib/lingo/error.rb,
lib/lingo/filter.rb,
lib/lingo/config.rb,
lib/lingo/version.rb,
lib/lingo/language.rb,
lib/lingo/database.rb,
lib/lingo/progress.rb,
lib/lingo/attendee.rb,
lib/lingo/ctl/other.rb,
lib/lingo/ctl/files.rb,
lib/lingo/filter/pdf.rb,
lib/lingo/filter/xml.rb,
lib/lingo/text_utils.rb,
lib/lingo/array_utils.rb,
lib/lingo/ctl/analysis.rb,
lib/lingo/language/word.rb,
lib/lingo/language/char.rb,
lib/lingo/language/token.rb,
lib/lingo/database/source.rb,
lib/lingo/attendee/stemmer.rb,
lib/lingo/language/grammar.rb,
lib/lingo/language/lexical.rb,
lib/lingo/database/crypter.rb,
lib/lingo/attendee/debugger.rb,
lib/lingo/attendee/variator.rb,
lib/lingo/buffered_attendee.rb,
lib/lingo/deferred_attendee.rb,
lib/lingo/database/progress.rb,
lib/lingo/attendee/synonymer.rb,
lib/lingo/attendee/formatter.rb,
lib/lingo/attendee/tokenizer.rb,
lib/lingo/attendee/sequencer.rb,
lib/lingo/language/word_form.rb,
lib/lingo/attendee/decomposer.rb,
lib/lingo/attendee/lsi_filter.rb,
lib/lingo/attendee/hal_filter.rb,
lib/lingo/language/dictionary.rb,
lib/lingo/database/hash_store.rb,
lib/lingo/database/sdbm_store.rb,
lib/lingo/database/gdbm_store.rb,
lib/lingo/attendee/abbreviator.rb,
lib/lingo/attendee/text_writer.rb,
lib/lingo/attendee/text_reader.rb,
lib/lingo/attendee/debug_filter.rb,
lib/lingo/attendee/multi_worder.rb,
lib/lingo/language/lexical_hash.rb,
lib/lingo/database/libcdb_store.rb,
lib/lingo/attendee/object_filter.rb,
lib/lingo/attendee/word_searcher.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/single_word.rb,
lib/lingo/database/source/multi_value.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: ArrayUtils, 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'  }
}
ENCODING =

Default encoding

'UTF-8'.freeze
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



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

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

  @config_args = args
  reset(false)
end

Instance Attribute Details

#dictionariesObject (readonly)

Returns the value of attribute dictionaries



239
240
241
# File 'lib/lingo.rb', line 239

def dictionaries
  @dictionaries
end

Class Method Details

.append_path(*path) ⇒ Object



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

def append_path(*path)
  include_path(path)
end

.basename(type, file) ⇒ Object



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

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

.basepath(type, file) ⇒ Object



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

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

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



80
81
82
# File 'lib/lingo.rb', line 80

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



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/lingo.rb', line 100

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



132
133
134
135
136
# File 'lib/lingo.rb', line 132

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

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



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/lingo.rb', line 84

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



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

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

.talk(*args) ⇒ Object



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

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

Instance Method Details

#configObject



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

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

#database_config(id) ⇒ Object



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

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



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

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

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



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
300
301
302
303
304
# File 'lib/lingo.rb', line 273

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



258
259
260
# File 'lib/lingo.rb', line 258

def lexical_hash(src)
  @lexical_hash[src]
end

#reset(close = true) ⇒ Object



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

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



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

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

#talkObject



262
263
264
265
266
267
268
269
270
271
# File 'lib/lingo.rb', line 262

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

  Debug.ps(:lingo_talk)
ensure
  reset
end

#warn(*msg) ⇒ Object



316
317
318
# File 'lib/lingo.rb', line 316

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