Class: FFI::Aspell::Speller

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi/aspell/speller.rb

Overview

The Speller class is used for spell checking individual words as well as generating a list of suggestions.

Usage

First you'll have to create a new instance:

speller = FFI::Aspell::Speller.new

When creating a new instance you can specify the language as well as a set of arbitrary Aspell options (e.g. the personal wordlist file). The language can be set in the first parameter, other options are set as a hash in the second parameter:

speller = FFI::Aspell::Speller.new('nl', :personal => 'aspell.nl.pws')

Unlike Raspell the keys of the hash used for additional options can be both strings and symbols.

Once an instance has been created you can change the options, check the spelling of a word or retrieve a list of suggestions.

Options

There are four methods for dealing with Aspell options:

There are also two extra methods which can be used to set the suggestion mode, both these methods are simply shortcuts and use the #set() method for actually setting the values:

speller.suggestion_mode = 'fast'

if speller.suggestion_mode == 'fast'
  # ...
end

Setting an option:

speller.set('lang', 'en_US')

Retrieving an option:

speller.get('lang')

Resetting an option:

speller.reset('lang')

Checking a Word

Checking the spelling of a word is done using #correct?. This method takes a string containing the word to verify and returns true if the word is spelled correctly and false otherwise:

speller.correct?('cookie') # => true
speller.correct?('cookei') # => false

Suggestions

Suggestions can be generated using suggestions. This method returns an array containing all the possible suggestions based on the suggestion mode that is being used:

speller.suggestions('cookei') # => ["cookie", ...]

Cleaning up

When you're finished with the Speller object, you can let the finalizer automatically free resources, otherwise, call #close to explicitly free the underlying resources:

speller = FFI::Aspell::Speller.new
speller.correct?('cookie') # => true
speller.close

Alternatively, you can use the block form of Speller.open to automatically free the resources:

FFI::Aspell::Speller.open do |speller|
  puts speller.correct?('cookie') # => prints "true"
end

Speller.open takes the same parameters as Speller.new.

For more information see the documentation of the individual methods in this class.

Constant Summary collapse

SUGGESTION_MODES =

Array containing the possible suggestion modes to use.

Returns:

  • (Array)
['ultra', 'fast', 'normal', 'bad-spellers']

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(language = nil, options = {}) ⇒ Speller

Creates a new instance of the class, sets the language as well as the options specified in the options hash.

Parameters:

  • language (String) (defaults to: nil)

    The language to use.

  • options (Hash) (defaults to: {})

    A hash containing extra configuration options, such as the "personal" option to set.



155
156
157
158
159
160
161
162
163
# File 'lib/ffi/aspell/speller.rb', line 155

def initialize(language = nil, options = {})
  @config = Aspell.config_new

  options['lang'] = language if language

  options.each { |k, v| set(k, v) }

  update_speller
end

Class Method Details

.finalizer(config, speller) ⇒ Proc

Returns a proc for a finalizer, used for cleaning up native resources.

Parameters:

  • config (FFI::Pointer)
  • speller (FFI::Pointer)

Returns:

  • (Proc)


139
140
141
142
143
144
# File 'lib/ffi/aspell/speller.rb', line 139

def self.finalizer(config, speller)
  return proc {
    Aspell.config_delete(config)
    Aspell.speller_delete(speller)
  }
end

.open(*args) {|speller| ... } ⇒ Speller

Creates a new instance of the class. If a block is given, the instance is yielded and automatically closed when exiting the block.

Yields:

  • If a block is given, the speller instance is yielded.

Yield Parameters:

  • speller (Speller)

    The created speller. #close is automatically called when exiting the block.

Returns:

See Also:

  • [[#initialize]


118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/ffi/aspell/speller.rb', line 118

def self.open(*args)
  speller = self.new(*args)

  if block_given?
    begin
      yield speller
    ensure
      speller.close
    end
  end

  return speller
end

Instance Method Details

#available_dictionariesArray (private)

Get all availbale aspell dictionary codes

Returns:

  • (Array)


451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# File 'lib/ffi/aspell/speller.rb', line 451

def available_dictionaries
  list     = Aspell.dict_info_list(@config)
  elements = Aspell.dict_info_list_elements(list)
  dicts    = []

  while element = Aspell.dict_info_enumeration_next(elements)
    break if element == FFI::Pointer::NULL

    dict_info = Aspell::DictInfo.new(element)

    dicts << handle_output(dict_info[:code])
    dicts << handle_output(dict_info[:code]).gsub("_", "-")
  end

  Aspell.delete_dict_info_enumeration(elements)

  return dicts
end

#check_closednil (private)

Raises error if speller is closed.

Returns:

  • (nil)

Raises:

  • (RuntimeError)

    Raised if the speller is closed.



405
406
407
408
409
# File 'lib/ffi/aspell/speller.rb', line 405

def check_closed
  if closed?
    raise(RuntimeError, 'This Speller object has already been closed')
  end
end

#check_dictionarynil (private)

Raises error if used dictionary is not installed.

Returns:

  • (nil)

Raises:

  • (ArgumentError)

    Raised if dictionary does not exist.



417
418
419
420
421
422
423
424
425
426
# File 'lib/ffi/aspell/speller.rb', line 417

def check_dictionary
  dictionary = get('lang')

  unless dictionary_available?(dictionary)
    raise(
      ArgumentError,
      "The used dictionary #{dictionary.inspect} is not available"
    )
  end
end

#closeObject

Closes the speller and frees underlying resources. Calling this is not absolutely required as the resources will eventually be freed by the finalizer.

Raises:

  • (RuntimeError)

    Raised if the speller is closed.



172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/ffi/aspell/speller.rb', line 172

def close
  check_closed

  # Remove finalizer since we're manually freeing resources.
  ObjectSpace.undefine_finalizer(self)

  Aspell.config_delete(@config)

  @config = nil

  Aspell.speller_delete(@speller)

  @speller = nil
end

#closed?TrueClass|FalseClass

Checks if the speller is closed or not.

Returns:

  • (TrueClass|FalseClass)


192
193
194
# File 'lib/ffi/aspell/speller.rb', line 192

def closed?
  return @config.nil?
end

#correct?(word) ⇒ TrueClass|FalseClass

Checks if the given word is correct or not.

Parameters:

  • word (String)

    The word to check.

Returns:

  • (TrueClass|FalseClass)

Raises:

  • (RuntimeError)

    Raised if the speller is closed.



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/ffi/aspell/speller.rb', line 212

def correct?(word)
  check_closed

  unless word.is_a?(String)
    raise(TypeError, "Expected String but got #{word.class} instead")
  end

  correct = Aspell.speller_check(
    @speller,
    handle_input(word.to_s),
    word.bytesize
  )

  return correct
end

#dictionary_available?(dictionary) ⇒ TrueClass|FalseClass

Checks if a dictionary is available or not

Returns:

  • (TrueClass|FalseClass)


201
202
203
# File 'lib/ffi/aspell/speller.rb', line 201

def dictionary_available?(dictionary)
  return available_dictionaries.include?(dictionary)
end

#get(key) ⇒ String

Retrieves the value of the specified configuration item.

Parameters:

  • key (#to_s)

    The configuration key to retrieve.

Returns:

  • (String)

Raises:

  • (RuntimeError)

    Raised if the speller is closed.

  • (FFI::Aspell::ConfigError)

    Raised when the configuration item does not exist.



317
318
319
320
321
322
323
324
325
326
327
# File 'lib/ffi/aspell/speller.rb', line 317

def get(key)
  check_closed

  value = Aspell.config_retrieve(@config, key.to_s)

  if value
    return value
  else
    raise(ConfigError, "The configuration item #{key} does not exist")
  end
end

#get_default(key) ⇒ String

Retrieves the default value for the given configuration key.

Parameters:

  • key (#to_s)

    The name of the configuration key.

Returns:

  • (String)

Raises:

  • (RuntimeError)

    Raised if the speller is closed.

  • (FFI::Aspell::ConfigError)

    Raised when the configuration item does not exist.



338
339
340
341
342
343
344
345
346
347
348
# File 'lib/ffi/aspell/speller.rb', line 338

def get_default(key)
  check_closed

  value = Aspell.config_retrieve_default(@config, key.to_s)

  if value
    return value
  else
    raise(ConfigError, "The configuration item #{key} does not exist")
  end
end

#handle_input(word) ⇒ String (private)

Converts word to encoding expected in aspell from current ruby encoding

Parameters:

  • word (String)

    The word to convert

Returns:

  • (String)

    word



381
382
383
384
385
# File 'lib/ffi/aspell/speller.rb', line 381

def handle_input(word)
  enc = get('encoding')

  return word.encode(enc)
end

#handle_output(word) ⇒ String (private)

Converts word from aspell encoding to what ruby expects

Parameters:

  • word (String)

    The word to convert

Returns:

  • (String)

    word



393
394
395
396
397
# File 'lib/ffi/aspell/speller.rb', line 393

def handle_output(word)
  enc = get('encoding')

  return word.force_encoding(enc).encode
end

#reset(key) ⇒ Object

Resets a configuration item to its default value.

Parameters:

  • key (#to_s)

    The name of the configuration item to reset.

Raises:

  • (RuntimeError)

    Raised if the speller is closed.

  • (FFI::Aspell::ConfigError)

    Raised when the configuration item could not be reset.



358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/ffi/aspell/speller.rb', line 358

def reset(key)
  check_closed

  unless Aspell.config_remove(@config, key.to_s)
    raise(
      ConfigError,
      "The configuration item #{key} could not be reset, most likely " \
        "it doesn't exist"
    )
  end

  update_speller
end

#set(key, value) ⇒ Object

Sets a configuration option.

Parameters:

  • key (#to_s)

    The configuration key to set.

  • value (#to_s)

    The value of the configuration key.

Raises:

  • (RuntimeError)

    Raised if the speller is closed.

  • (FFI::Aspell::ConfigError)

    Raised when the configuration value could not be set or when an incorrect suggestion mode was given.



294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/ffi/aspell/speller.rb', line 294

def set(key, value)
  check_closed

  if key == 'sug-mode' and !SUGGESTION_MODES.include?(value)
    raise(ConfigError, "The suggestion mode #{value} is invalid")
  end

  unless Aspell.config_replace(@config, key.to_s, value.to_s)
    raise(ConfigError, "Failed to set the configuration item #{key}")
  end

  update_speller
end

#suggestion_modeString

Returns the suggestion mode that's currently used.

Returns:

  • (String)

Raises:

  • (RuntimeError)

    Raised if the speller is closed.



279
280
281
282
283
# File 'lib/ffi/aspell/speller.rb', line 279

def suggestion_mode
  check_closed

  return get('sug-mode')
end

#suggestion_mode=(mode) ⇒ Object

Sets the suggestion mode for #suggestions.

Parameters:

  • mode (String)

    The suggestion mode to use.

Raises:

  • (RuntimeError)

    Raised if the speller is closed.



267
268
269
270
271
# File 'lib/ffi/aspell/speller.rb', line 267

def suggestion_mode=(mode)
  check_closed

  set('sug-mode', mode)
end

#suggestions(word) ⇒ Array

Returns an array containing words suggested as an alternative to the specified word.

Parameters:

  • word (String)

    The word for which to generate a suggestion list.

Returns:

  • (Array)

Raises:

  • (RuntimeError)

    Raised if the speller is closed.



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/ffi/aspell/speller.rb', line 236

def suggestions(word)
  check_closed

  unless word.is_a?(String)
    raise(TypeError, "Expected String but got #{word.class} instead")
  end

  list = Aspell.speller_suggest(
    @speller,
    handle_input(word),
    word.bytesize
  )

  suggestions = []
  elements    = Aspell.word_list_elements(list)

  while word = Aspell.string_enumeration_next(elements)
    suggestions << handle_output(word)
  end

  Aspell.string_enumeration_delete(elements)

  return suggestions
end

#update_spellerObject (private)

Updates the internal speller object to use the current config.



431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/ffi/aspell/speller.rb', line 431

def update_speller
  ObjectSpace.undefine_finalizer(self)

  Aspell.speller_delete(@speller)

  @speller = Aspell.speller_new(@config)

  ObjectSpace.define_finalizer(
    self,
    self.class.finalizer(@config, @speller)
  )

  check_dictionary
end