thinking-sphinx-raspell 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.textile +51 -0
- data/VERSION.yml +4 -0
- data/lib/thinking_sphinx/raspell.rb +76 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/thinking_sphinx/raspell_spec.rb +56 -0
- metadata +99 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Pat Allan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
h1. Thinking Sphinx with Raspell
|
2
|
+
|
3
|
+
This library adds Aspell/Raspell support to "Thinking Sphinx":http://ts.freelancing-gods.com.
|
4
|
+
|
5
|
+
h2. Installation
|
6
|
+
|
7
|
+
You'll need "the Aspell library":http://www.aspell.net (easily compiled by source, or installed via MacPorts). Don't forget to install the English library as well - there's instructions for both in Evan Weaver's "Raspell README":http://github.com/fauna/raspell.
|
8
|
+
|
9
|
+
Once that's set up, grab the gem from "GemCutter":http://gemcutter.org:
|
10
|
+
|
11
|
+
<pre><code>sudo gem install thinking-sphinx-raspell \
|
12
|
+
--source http://gemcutter.org</code></pre>
|
13
|
+
|
14
|
+
You'll want to add the gem to your @config/environment.rb@ file (assuming you're working on a Rails application):
|
15
|
+
|
16
|
+
<pre><code>config.gem('thinking-sphinx-raspell',
|
17
|
+
:lib => 'thinking_sphinx/raspell',
|
18
|
+
:source => 'http://gemcutter.org',
|
19
|
+
:version => '>= 1.0.0'
|
20
|
+
)</code></pre>
|
21
|
+
|
22
|
+
Or, if you wish to do a manual require yourself:
|
23
|
+
|
24
|
+
<pre><code>require 'thinking_sphinx/raspell'</code></pre>
|
25
|
+
|
26
|
+
h2. Usage
|
27
|
+
|
28
|
+
By default, Thinking Sphinx will not overwrite your search query, but you can view suggestions:
|
29
|
+
|
30
|
+
<pre><code>@articles = Article.search 'pnacakes'
|
31
|
+
@articles.suggestion? #=> true
|
32
|
+
@articles.suggestion #=> 'pancakes'</code></pre>
|
33
|
+
|
34
|
+
You can also choose to redo the search using the provided suggestion:
|
35
|
+
|
36
|
+
<pre><code>@articles.redo_with_suggestion
|
37
|
+
@articles.each do |article|
|
38
|
+
# ...
|
39
|
+
end</code></pre>
|
40
|
+
|
41
|
+
h2. Limitations
|
42
|
+
|
43
|
+
* Currently only uses (and thus requires) the en_US dictionary.
|
44
|
+
* Spelling suggestions are done via Raspell's normal mode, and are case insensitive.
|
45
|
+
* Only checks normal query strings, not field-specific queries via the @:conditions@ hash.
|
46
|
+
|
47
|
+
Patches are very much welcome - I would like to address all of the above limitations.
|
48
|
+
|
49
|
+
h2. Copyright
|
50
|
+
|
51
|
+
Copyright (c) 2009 "Pat Allan":http://freelancing-gods.com. Released under an MIT licence.
|
data/VERSION.yml
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'raspell'
|
2
|
+
|
3
|
+
module ThinkingSphinx
|
4
|
+
# Module for adding suggestion support into Thinking Sphinx. This gets
|
5
|
+
# included into ThinkingSphinx::Search.
|
6
|
+
#
|
7
|
+
# @author Pat Allan
|
8
|
+
#
|
9
|
+
module Raspell
|
10
|
+
# The original query, with words considered mispelt replaced with the first
|
11
|
+
# suggestion from Aspell/Raspell.
|
12
|
+
#
|
13
|
+
# @return [String] the suggested query
|
14
|
+
#
|
15
|
+
def suggestion
|
16
|
+
@suggestion ||= all_args.gsub(/[\w\']+/) { |word| corrected_word(word) }
|
17
|
+
end
|
18
|
+
|
19
|
+
# An indication of whether there are any spelling corrections for the
|
20
|
+
# original query.
|
21
|
+
#
|
22
|
+
# @return [Boolean] true if the suggested query is different from the
|
23
|
+
# original
|
24
|
+
#
|
25
|
+
def suggestion?
|
26
|
+
suggestion != query
|
27
|
+
end
|
28
|
+
|
29
|
+
# Modifies the current search object, switching queries and removing any
|
30
|
+
# previously stored results.
|
31
|
+
#
|
32
|
+
def redo_with_suggestion
|
33
|
+
@query = nil
|
34
|
+
@args = [suggestion]
|
35
|
+
@populated = false
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# The search query as a single string, excluding any field-focused values
|
41
|
+
# provided using the :conditions option.
|
42
|
+
#
|
43
|
+
# @return [String] all query arguments joined together by spaces.
|
44
|
+
#
|
45
|
+
def all_args
|
46
|
+
args.join(' ')
|
47
|
+
end
|
48
|
+
|
49
|
+
# The first spelling suggestion, if the given word is considered incorrect,
|
50
|
+
# otherwise the word is returned unchanged.
|
51
|
+
#
|
52
|
+
# @param [String] word The word to check.
|
53
|
+
# @return [String] Spelling correction for the given word.
|
54
|
+
#
|
55
|
+
def corrected_word(word)
|
56
|
+
speller.check(word) ? word : speller.suggest(word).first
|
57
|
+
end
|
58
|
+
|
59
|
+
# Aspell instance with all appropriate settings defined (dictionary set to
|
60
|
+
# en_US, suggestion mode set to Aspell::NORMAL, and ignore-case set to
|
61
|
+
# true).
|
62
|
+
#
|
63
|
+
# @return [Aspell] the prepared Aspell instance
|
64
|
+
#
|
65
|
+
def speller
|
66
|
+
@speller ||= begin
|
67
|
+
speller = Aspell.new('en_US')
|
68
|
+
speller.suggestion_mode = Aspell::NORMAL
|
69
|
+
speller.set_option "ignore-case", "true"
|
70
|
+
speller
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
ThinkingSphinx::Search.send(:include, ThinkingSphinx::Raspell)
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
|
7
|
+
require 'thinking_sphinx'
|
8
|
+
require 'raspell'
|
9
|
+
require 'thinking_sphinx/raspell'
|
10
|
+
|
11
|
+
Spec::Runner.configure do |config|
|
12
|
+
#
|
13
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe ThinkingSphinx::Search do
|
4
|
+
describe '#suggestion' do
|
5
|
+
it "should return a spelling suggestion, if there is one" do
|
6
|
+
search = ThinkingSphinx::Search.new('wodrs incorret on purpose')
|
7
|
+
search.suggestion.should == 'words incorrect on purpose'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be actual query if there is no suggestion" do
|
11
|
+
search = ThinkingSphinx::Search.new('words all correct here')
|
12
|
+
search.suggestion.should == 'words all correct here'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#suggestion?' do
|
17
|
+
it "should return true if there is a spelling suggestion" do
|
18
|
+
search = ThinkingSphinx::Search.new('wodrs incorret on purpose')
|
19
|
+
search.suggestion?.should be_true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return false if there is no spelling suggestion" do
|
23
|
+
search = ThinkingSphinx::Search.new('words all correct here')
|
24
|
+
search.suggestion?.should be_false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#redo_with_suggestion' do
|
29
|
+
before :each do
|
30
|
+
@config = ThinkingSphinx::Configuration.instance
|
31
|
+
@client = Riddle::Client.new
|
32
|
+
|
33
|
+
@config.stub!(:client => @client)
|
34
|
+
@client.stub!(:query => {:matches => [], :total_found => 0, :total => 0})
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should repeat the query with the spelling suggestion" do
|
38
|
+
@client.should_receive(:query) do |query, index, comment|
|
39
|
+
query.should == 'words incorrect on purpose'
|
40
|
+
end
|
41
|
+
|
42
|
+
search = ThinkingSphinx::Search.new('wodrs incorret on purpose')
|
43
|
+
search.redo_with_suggestion
|
44
|
+
search.first
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should redo the query if it's already been populated" do
|
48
|
+
@client.should_receive(:query).twice
|
49
|
+
|
50
|
+
search = ThinkingSphinx::Search.new('wodrs incorret on purpose')
|
51
|
+
search.first
|
52
|
+
search.redo_with_suggestion
|
53
|
+
search.first
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: thinking-sphinx-raspell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pat Allan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-04 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thinking-sphinx
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.12
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: raspell
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "1.1"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: yard
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
description: Adds spelling suggestions to Thinking Sphinx searches.
|
56
|
+
email: pat@freelancing-gods.com
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- LICENSE
|
63
|
+
- README.textile
|
64
|
+
files:
|
65
|
+
- LICENSE
|
66
|
+
- README.textile
|
67
|
+
- VERSION.yml
|
68
|
+
- lib/thinking_sphinx/raspell.rb
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://ts.freelancing-gods.com
|
71
|
+
licenses: []
|
72
|
+
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options:
|
75
|
+
- --charset=UTF-8
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: "0"
|
83
|
+
version:
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: "0"
|
89
|
+
version:
|
90
|
+
requirements: []
|
91
|
+
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.3.5
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: An add-on gem for spelling suggestions in Thinking Sphinx
|
97
|
+
test_files:
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
- spec/thinking_sphinx/raspell_spec.rb
|