class Lingo
Constants
- BASE
The system-wide Lingo directory (
LINGO_BASE
).- CURR
The local Lingo directory (
LINGO_CURR
).- ENCODING
Default encoding
- FIND_OPTIONS
Map of file types to their standard location and file extension.
- HOME
The user's personal Lingo directory (
LINGO_HOME
).- PATH
The search path for Lingo dictionary and configuration files.
- SEP_RE
- VERSION
Attributes
dictionaries[R]
Public Class Methods
CLI(args, extra = nil, &block)
click to toggle source
# File lib/lingo/cli.rb, line 79 def self.CLI(args, extra = nil, &block) opt, req = args.partition { |arg| arg.sub!(/\?\z/, '') } unless (n = ARGV.size - req.size) >= 0 && n <= opt.size msg = "Usage: #{$0}#{args.map { |arg| [' ', arg].zip( opt.include?(arg) ? %w[[ ]] : %w[< >]).join }.join}" abort Array(extra).unshift(msg).join("\n\n") end Object.new.extend(TextUtils).instance_eval(&block) rescue LingoError => err abort err.to_s ensure ObjectSpace.each_object(Zlib::GzipWriter, &:close) end
append_path(*path)
click to toggle source
# File lib/lingo.rb, line 123 def append_path(*path) include_path(path) end
basename(type, file)
click to toggle source
# File lib/lingo.rb, line 114 def basename(type, file) dir, name = File.split(file) type != :dict ? name : File.join(File.basename(dir), name) end
basepath(type, file)
click to toggle source
# File lib/lingo.rb, line 119 def basepath(type, file) File.join(options_for(type)[:dir], basename(type, file)) end
call(cfg = find(:config, 'lingo-call'), args = [], &block)
click to toggle source
# File lib/lingo.rb, line 79 def call(cfg = find(:config, 'lingo-call'), args = [], &block) Call.new(['-c', cfg, *args]).call(&block) end
find(type, file, options = {}) { |err| ... }
click to toggle source
# File lib/lingo.rb, line 99 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)
click to toggle source
# File lib/lingo.rb, line 131 def get_const(name, klass = self) klass.const_get(name.camelcase) rescue NameError raise NameNotFoundError.new(klass, name) end
list(type, options = {})
click to toggle source
# File lib/lingo.rb, line 83 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
new(*args)
click to toggle source
# File lib/lingo.rb, line 231 def initialize(*args) Debug.ps(:lingo_new) @config_args = args reset(false) end
prepend_path(*path)
click to toggle source
# File lib/lingo.rb, line 127 def prepend_path(*path) include_path(path, true) end
talk(*args)
click to toggle source
# File lib/lingo.rb, line 75 def talk(*args) new(*args).talk end
Private Class Methods
file_with_ext(file, options)
click to toggle source
# File lib/lingo.rb, line 204 def file_with_ext(file, options) ext = options[:ext] ext && File.extname(file).empty? ? "#{file}.#{ext}" : file end
find_file(file, path, options)
click to toggle source
# File lib/lingo.rb, line 143 def find_file(file, path, options) if glob = options[:glob] file = File.chomp_ext(file) options[:ext] ||= '*' end file = file_with_ext(file, options) pn = Pathname.new(file).cleanpath if pn.relative? walk(path, options) { |dir| pn2 = pn.expand_path(dir) ex = pn2.exist? pn2 = Pathname.glob(pn2).first if glob && !ex pn = pn2 and break if glob ? pn2 : ex } end realpath_for(pn, path) rescue Errno::ENOENT raise unless relax = options[:relax] relax.respond_to?(:[]) ? relax[file] : file end
find_store(file, path, options)
click to toggle source
# File lib/lingo.rb, line 168 def find_store(file, path, options) base = basename(:dict, find(:dict, file, path) { raise SourceFileNotFoundError.new(nil, find_file(file, path, options.merge(glob: true, relax: lambda { |_file| raise SourceFileNotFoundError.new(file, _file) }) )) }) walk(path.reverse, options, false) { |dir| Pathname.new(dir).ascend { |i| begin stat = i.stat break true if stat.file? || !stat.writable? return File.chomp_ext(File.join(dir, base)) rescue Errno::ENOENT end } } raise NoWritableStoreError.new(file, path) end
include_path(path, pre = false)
click to toggle source
# File lib/lingo.rb, line 139 def include_path(path, pre = false) PATH.insert(pre ? 0 : -1, *path.map! { |i| i.to_s }) end
options_for(type, options = {})
click to toggle source
# File lib/lingo.rb, line 192 def options_for(type, options = {}) if find_options = FIND_OPTIONS[type] options = find_options.merge(options) else raise ArgumentError, "Invalid type `#{type.inspect}'", caller(1) end end
path_for(options)
click to toggle source
# File lib/lingo.rb, line 200 def path_for(options) options[:path] || PATH end
realpath_for(pn, path)
click to toggle source
# File lib/lingo.rb, line 220 def realpath_for(pn, path) pn.realpath(path.first).to_s end
require_optional(lib)
click to toggle source
# File lib/lingo.rb, line 224 def require_optional(lib) require lib unless ENV["LINGO_NO_#{lib.upcase}"] rescue LoadError end
walk(path, options, legacy = true) { |join| ... }
click to toggle source
# File lib/lingo.rb, line 209 def walk(path, options, legacy = true) dirs, seen = [options[:dir].to_s], Hash.seen dirs << '' if legacy dirs.uniq! path.each { |d| next if seen[d = File.expand_path(d)] dirs.each { |i| yield File.join(d, i) } or break } end
Public Instance Methods
attendees(arg = Object)
click to toggle source
# File lib/lingo.rb, line 305 def attendees(arg = Object) @attendees.grep(arg.is_a?(Class) ? arg : Attendee.const_get(arg.to_s.camelcase)) end
config()
click to toggle source
# File lib/lingo.rb, line 240 def config @config ||= Config.new(*@config_args) rescue => err raise ConfigLoadError.new(err) end
database_config(id)
click to toggle source
# File lib/lingo.rb, line 250 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_config()
click to toggle source
# File lib/lingo.rb, line 246 def dictionary_config @dictionary_config ||= config['language/dictionary'] end
invite(list = config['meeting/attendees'])
click to toggle source
# File lib/lingo.rb, line 272 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)
click to toggle source
# File lib/lingo.rb, line 257 def lexical_hash(src) @lexical_hash[src] end
reset(close = true)
click to toggle source
# File lib/lingo.rb, line 314 def reset(close = true) dictionaries.each { |i| i.close } if close @dictionaries, @attendees = [], [] @lexical_hash = Hash.nest { |k| Language::LexicalHash.new(k, self) } end
start()
click to toggle source
# File lib/lingo.rb, line 310 def start @attendees.first.control(:TALK) end
talk()
click to toggle source
# File lib/lingo.rb, line 261 def talk Debug.profile(config['profile']) { invite start } Debug.ps(:lingo_talk) ensure reset end
warn(*msg)
click to toggle source
# File lib/lingo.rb, line 320 def warn(*msg) config.warn(*msg) end