diff --git a/c-shared.go b/c-shared.go index 05b96d3..7eb806e 100644 --- a/c-shared.go +++ b/c-shared.go @@ -205,6 +205,22 @@ func varnam_transliterate_advanced(varnamHandleID C.int, id C.int, word *C.char, } } +//export varnam_transliterate_greedy_tokenized +func varnam_transliterate_greedy_tokenized(varnamHandleID C.int, word *C.char, resultPointer **C.varray) C.int { + handle := getVarnamHandle(varnamHandleID) + + result := handle.varnam.TransliterateGreedyTokenized(C.GoString(word)) + + ptr := C.varray_init() + for _, sug := range result { + cSug := unsafe.Pointer(C.makeSuggestion(C.CString(sug.Word), C.int(sug.Weight), C.int(sug.LearnedOn))) + C.varray_push(ptr, cSug) + } + *resultPointer = ptr + + return C.VARNAM_SUCCESS +} + //export varnam_reverse_transliterate func varnam_reverse_transliterate(varnamHandleID C.int, word *C.char, resultPointer **C.varray) C.int { handle := getVarnamHandle(varnamHandleID) @@ -442,6 +458,25 @@ func varnam_get_recently_learned_words(varnamHandleID C.int, id C.int, offset C. return C.VARNAM_SUCCESS } +//export varnam_get_suggestions +func varnam_get_suggestions(varnamHandleID C.int, id C.int, word *C.char, resultPointer **C.varray) C.int { + ctx, cancel := makeContext(id) + defer cancel() + + handle := getVarnamHandle(varnamHandleID) + + result := handle.varnam.GetSuggestions(ctx, C.GoString(word)) + + ptr := C.varray_init() + for _, sug := range result { + cSug := unsafe.Pointer(C.makeSuggestion(C.CString(sug.Word), C.int(sug.Weight), C.int(sug.LearnedOn))) + C.varray_push(ptr, cSug) + } + *resultPointer = ptr + + return C.VARNAM_SUCCESS +} + func makeCSchemeDetails(sd govarnam.SchemeDetails) *C.struct_SchemeDetails_t { var cIsStable C.int diff --git a/govarnam/dictionary.go b/govarnam/dictionary.go index 83f26fd..e3e9924 100644 --- a/govarnam/dictionary.go +++ b/govarnam/dictionary.go @@ -398,3 +398,15 @@ func (varnam *Varnam) GetRecentlyLearntWords(ctx context.Context, offset int, li return result, nil } } + +// GetSuggestions get word suggestions from dictionary +func (varnam *Varnam) GetSuggestions(ctx context.Context, word string) []Suggestion { + var sugs []Suggestion + + select { + case <-ctx.Done(): + return sugs + default: + return varnam.searchDictionary(ctx, []string{word}, true) + } +} diff --git a/govarnam/govarnam.go b/govarnam/govarnam.go index 46bdbb7..cd62c81 100644 --- a/govarnam/govarnam.go +++ b/govarnam/govarnam.go @@ -385,12 +385,12 @@ func (varnam *Varnam) TransliterateWithContext(ctx context.Context, word string, } } -// TransliterateGreedy transliterate word without all possible suggestions in result -func (varnam *Varnam) TransliterateGreedy(word string) TransliterationResult { +// TransliterateGreedyTokenized transliterate word, only tokenizer results +func (varnam *Varnam) TransliterateGreedyTokenized(word string) []Suggestion { ctx := context.Background() - _, result := varnam.transliterate(ctx, word) - return result + tokens := varnam.tokenizeWord(ctx, word, VARNAM_MATCH_EXACT, false) + return varnam.tokensToSuggestions(ctx, tokens, false, varnam.TokenizerSuggestionsLimit) } // ReverseTransliterate do a reverse transliteration diff --git a/govarnam/govarnam_ml_test.go b/govarnam/govarnam_ml_test.go index a3b4747..5f61209 100644 --- a/govarnam/govarnam_ml_test.go +++ b/govarnam/govarnam_ml_test.go @@ -398,7 +398,7 @@ func TestMLDictionaryMatchExact(t *testing.T) { varnam.DictionaryMatchExact = false } -func TestRecentlyLearnedWords(t *testing.T) { +func TestMLRecentlyLearnedWords(t *testing.T) { varnam := getVarnamInstance("ml") words := []string{"ആലപ്പുഴ", "എറണാകുളം", "തൃശ്ശൂർ", "പാലക്കാട്", "കോഴിക്കോട്"} @@ -418,3 +418,18 @@ func TestRecentlyLearnedWords(t *testing.T) { result, err = varnam.GetRecentlyLearntWords(context.Background(), 4, len(words)) assertEqual(t, result[0].Word, "ആലപ്പുഴ") } + +func TestMLGetSuggestions(t *testing.T) { + varnam := getVarnamInstance("ml") + + words := []string{"ആലപ്പുഴ", "ആലം", "ആലാപനം"} + for _, word := range words { + varnam.Learn(word, 0) + } + + varnam.DictionarySuggestionsLimit = 5 + result := varnam.GetSuggestions(context.Background(), "ആല") + assertEqual(t, len(result), 3) + + assertEqual(t, result[0].Word, "ആലപ്പുഴ") +} diff --git a/govarnamgo/govarnamgo.go b/govarnamgo/govarnamgo.go index 3aff08d..dc76152 100644 --- a/govarnamgo/govarnamgo.go +++ b/govarnamgo/govarnamgo.go @@ -16,6 +16,7 @@ import "C" import ( "context" "fmt" + "log" "unsafe" ) @@ -370,6 +371,32 @@ func (handle *VarnamHandle) TransliterateAdvanced(ctx context.Context, word stri } } +// TransliterateGreedyTokenized transliterate but only tokenizer output +func (handle *VarnamHandle) TransliterateGreedyTokenized(word string) []Suggestion { + var result []Suggestion + + var resultPointer *C.varray + + cWord := C.CString(word) + defer C.free(unsafe.Pointer(cWord)) + + code := C.varnam_transliterate_greedy_tokenized(handle.connectionID, cWord, &resultPointer) + if code != C.VARNAM_SUCCESS { + log.Print(handle.GetLastError()) + return result + } + + i := 0 + for i < int(C.varray_length(resultPointer)) { + cSug := (*C.Suggestion)(C.varray_get(resultPointer, C.int(i))) + sug := makeSuggestion(cSug) + result = append(result, sug) + i++ + } + + return result +} + // ReverseTransliterate reverse transilterate func (handle *VarnamHandle) ReverseTransliterate(word string) ([]Suggestion, error) { var sugs []Suggestion @@ -513,6 +540,42 @@ func (handle *VarnamHandle) GetRecentlyLearntWords(ctx context.Context, offset i } } +// GetSuggestions get suggestions for a word +func (handle *VarnamHandle) GetSuggestions(ctx context.Context, word string) ([]Suggestion, error) { + var result []Suggestion + + operationID := makeContextOperation() + + select { + case <-ctx.Done(): + C.varnam_cancel(operationID) + return result, nil + default: + var resultPointer *C.varray + + cWord := C.CString(word) + defer C.free(unsafe.Pointer(cWord)) + + code := C.varnam_get_suggestions(handle.connectionID, operationID, cWord, &resultPointer) + if code != C.VARNAM_SUCCESS { + return result, &VarnamError{ + ErrorCode: int(code), + Message: handle.GetLastError(), + } + } + + i := 0 + for i < int(C.varray_length(resultPointer)) { + cSug := (*C.Suggestion)(C.varray_get(resultPointer, C.int(i))) + sug := makeSuggestion(cSug) + result = append(result, sug) + i++ + } + + return result, nil + } +} + func makeGoSchemeDetails(cSD *C.struct_SchemeDetails_t) SchemeDetails { isStable := true if cSD.IsStable == 0 { diff --git a/govarnamgo/govarnamgo_ml_inscript_test.go b/govarnamgo/govarnamgo_ml_inscript_test.go new file mode 100644 index 0000000..f199973 --- /dev/null +++ b/govarnamgo/govarnamgo_ml_inscript_test.go @@ -0,0 +1,26 @@ +package govarnamgo + +import ( + "context" + "testing" +) + +func TestMLInscriptTransilterateGreedyTokenized(t *testing.T) { + varnam := getVarnamInstance("ml-inscript") + + assertEqual(t, varnam.TransliterateGreedyTokenized("EnhdhgB")[0].Word, "ആലപ്പുഴ") +} + +func TestMLInscriptGetSuggestions(t *testing.T) { + varnam := getVarnamInstance("ml-inscript") + + varnam.Learn("ഇടുക്കി", 0) + + sugs, err := varnam.GetSuggestions( + context.Background(), + varnam.TransliterateGreedyTokenized("F'")[0].Word, // ഇട + ) + checkError(err) + + assertEqual(t, sugs[0].Word, "ഇടുക്കി") +} diff --git a/govarnamgo/govarnamgo_test.go b/govarnamgo/govarnamgo_test.go index 60ed1c5..57ae434 100644 --- a/govarnamgo/govarnamgo_test.go +++ b/govarnamgo/govarnamgo_test.go @@ -60,6 +60,7 @@ func tearDown() { func TestMain(m *testing.M) { setUp("ml") + setUp("ml-inscript") m.Run() tearDown() }