| Message |
This will do it:
local METAPHONE_LENGTH = 4 -- how many characters of metaphone to get back
local EDIT_DISTANCE = 4 -- how close a word must be to appear in the list of suggestions
local CASE_SENSITIVE = false -- compare case? true or false
local make_upper -- this becomes the upper-case conversion function, see below
-- sort function for sorting the suggestions into edit-distance order
local function suggestions_compare (word)
return function (a, b)
local diff = utils.edit_distance (make_upper (a), word) -
utils.edit_distance (make_upper (b), word)
if diff == 0 then
return make_upper (a) < make_upper (b)
else
return diff < 0
end -- differences the same?
end -- compareit
end -- function suggestions_compare
function GetSpellCheckCorrections (word)
-- make a suitable function depending on whether they want case-sensitive or not
if CASE_SENSITIVE then
make_upper = function (s) return s end -- return original
else
make_upper = function (s) return s:upper () end -- make upper case
end -- case-sensitivity test
uc_word = make_upper (word) -- convert to upper-case if wanted
-- path to the spell check dictionaries
local directory = utils.info ().app_directory .. "spell\\"
-- open database on disk
db = assert (sqlite3.open( directory .. "spell.sqlite"))
-- table of suggestions, based on the metaphone
local keyed_suggestions = {}
-- get both metaphones
local m1, m2 = utils.metaphone (word, METAPHONE_LENGTH)
local function lookup_metaphone (m)
local found = false
for row in db:rows(string.format ("SELECT name FROM words WHERE metaphone = '%s'", m)) do
local word = row [1]
if make_upper (word) == uc_word then
found = true -- found exact match
break
end -- found
if utils.edit_distance (make_upper (word), uc_word) < EDIT_DISTANCE then
keyed_suggestions [word] = true
end -- close enough
end
return found
end -- lookup_metaphone
-- look up first metaphone
if lookup_metaphone (m1) then
db:close ()
return word, "ok"
end -- word found
-- try 2nd metaphone
if m2 then
if lookup_metaphone (m2) then
db:close ()
return word, "ok"
end -- word found
end -- have alternate metaphone
-- pull into indexed table
local suggestions = {}
for k in pairs (keyed_suggestions) do
table.insert (suggestions, k)
end -- for
table.sort (suggestions, suggestions_compare (uc_word))
db:close ()
return suggestions
end -- GetSpellCheckCorrections
Test it:
t = GetSpellCheckCorrections ("indstry")
tprint (t)
Output:
1="industry"
2="industry's"
3="windsurf"
This is based on the spellchecker.lua file. Note the 2nd return value is "ok" if it finds an exact match on the metaphone. You may or may not want to keep that. I can't remember what that is for.
[EDIT] Amended the two paths above that return "ok" to close the database first. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | top |
|