snowball / snowball.go

// snowball stemmer
// Example:
//  stemmer = snowball.New("english")
//  fmt.Println(stemmer.stem("running")) // Will print "run"
package snowball

import (
#include <stdlib.h>
#include "libstemmer.h"
import "C"

const (
	Version = "0.1.3"

// Stemmer structure
type Stemmer struct {
	lang string
	stmr *C.struct_sb_stemmer

// free C resources
func free(stmr *Stemmer) {
	if stmr.stmr != nil {
		stmr.stmr = nil

// New creates a new stemmer for lang
func New(lang string) (*Stemmer, error) {
	clang := C.CString(lang)

	stmr := &Stemmer{
		C.sb_stemmer_new(clang, nil),

	if stmr.stmr == nil {
		return nil, fmt.Errorf("can't create stemmer for lang %s", lang)

	runtime.SetFinalizer(stmr, free)

	return stmr, nil

// Lang return the stemmer language
func (stmr *Stemmer) Lang() string {
	return stmr.lang

// Stem returns them stem of word (e.g. running -> run)
func (stmr *Stemmer) Stem(word string) string {
	ptr := unsafe.Pointer(C.CString(word))

	w := (*C.sb_symbol)(ptr)
	res := unsafe.Pointer(C.sb_stemmer_stem(stmr.stmr, w,
	size := C.sb_stemmer_length(stmr.stmr)

	buf := C.GoBytes(res, size)
	return string(buf)

// List returns the list of languages supported by snowball
func List() []string {
	names := []string{}

	// We don't need to free since sb_stemmer_list return pointer to static variable
	cp := uintptr(unsafe.Pointer(C.sb_stemmer_list()))
	size := unsafe.Sizeof(uintptr(0))

	for {
		name := C.GoString(*(**C.char)(unsafe.Pointer(cp)))
		if len(name) == 0 {
		names = append(names, name)
		cp += size
	return names
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.