Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
101 changes: 101 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,104 @@ func main() {
return
})
```
Custom Usage
----
```go
package your_app

import (
"github.com/tjarratt/babble"
)

func main() {
c := babble.DictionaryConfig {
MinLength: 3,
MaxLength: 5,
}

babbler := babble.NewBabblerWithConfig(c)
babbler.Separator = "-"
println(babbler.Babble()) // excessive-yak-shaving (or some other phrase)

// optionally set your own separator
babbler.Separator = " "
println(babbler.Babble()) // "hello from nowhere" (or some other phrase)

// optionally set the number of words you want
babbler.Count = 1
println(babbler.Babble()) // antibiomicrobrial (or some other word)

```
Upcase
----
```go
package your_app

import (
babble2 "babble"
"github.com/tjarratt/babble"
)

func main() {
c := babble.DictionaryConfig {
MinLength: 3,
MaxLength: 5,
Upcase: true,
}

babbler := babble.NewBabblerWithConfig(c)
babbler.Separator = "-"
println(babbler.Babble()) // EXCESSIVE-YAK-SHAVING (or some other phrase)
```
Downcase
----
```go
c = babble.DictionaryConfig {
MinLength: 3,
MaxLength: 5,
Downcase: true,
}

babbler = babble.NewBabblerWithConfig(c)
babbler.Separator = "-"
println(babbler.Babble()) // excessive-yak-shaving (or some other phrase)
```
Transform
----
```go
var alternateCase = func (s string)string {
rs, upper := []rune(s), false
for i, r := range rs {
if unicode.IsLetter(r) {
if upper = !upper; upper {
rs[i] = unicode.ToUpper(r)
}
}
}
return string(rs)
}
c = babble.DictionaryConfig {
MinLength: 3,
MaxLength: 5,
TransformWord: alternateCase,
}

babbler = babble.NewBabblerWithConfig(c)
babbler.Separator = "-"
println(babbler.Babble()) // ExCeSsIvE-YaK-SlUrPiNg the transform is applied to each word individually during load
```
Custom Word List
----
```go
customList = []string{ "luke", "leia", "han", "darth", "r2d2" } // C-3PO has been expressly excluded
c = babble.DictionaryConfig {
MinLength: 3,
MaxLength: 5,
CustomWordList: customList,
}

babbler = babble.NewBabblerWithConfig(c)
babbler.Separator = "-"
println(babbler.Babble()) // luke-darth
```

16 changes: 14 additions & 2 deletions babble.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"time"
)

var words []string

func init() {
rand.Seed(time.Now().UnixNano())
}
Expand All @@ -14,12 +16,23 @@ type Babbler struct {
Count int
Separator string
Words []string
Dictionary Dictionary
}

func NewBabbler() (b Babbler) {
d := NewDictionaryWithConfig(DefaultDictionaryConfig)
b.Dictionary = d
b.Count = 2
b.Separator = "-"
b.Words = d.GetWordList()
return
}
func NewBabblerWithConfig(config DictionaryConfig) (b Babbler) {
d := NewDictionaryWithConfig(config)
b.Dictionary = d
b.Count = 2
b.Separator = "-"
b.Words = readAvailableDictionary()
b.Words = b.Dictionary.GetWordList()
return
}

Expand All @@ -28,6 +41,5 @@ func (this Babbler) Babble() string {
for i := 0; i < this.Count ; i++ {
pieces = append(pieces, this.Words[rand.Int()%len(this.Words)])
}

return strings.Join(pieces, this.Separator)
}
12 changes: 12 additions & 0 deletions babble_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,16 @@ var _ = Describe("babble", func() {
Expect(babbler.Babble()).To(Equal("hello☃hello"))
})
})

Describe("new babble", func(){
It("handles a basic configuration", func(){
babbler = NewBabbler()
Expect( len(babbler.Words) ).Should(Equal(babbler.Dictionary.GetListLength()))
})
It("accepts a custom dictionary config", func(){
babbler = NewBabblerWithConfig(DictionaryConfig{ MinLength: 2, MaxLength: 4})
Expect(len(babbler.Words)).Should(Equal(babbler.Dictionary.GetListLength()))
})

})
})
141 changes: 141 additions & 0 deletions dictionary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package babble

import "strings"

type ExcludeWord func(s string)bool
type TransformWord func(s string) string

type DictionaryConfig struct {
// Limits the lower bound to the length of words in the list
MinLength int
// Limits the upper bound to the length of words in the list
MaxLength int
// If this pointer is non-nil, this list is used instead of
// the default OS dictionary.
CustomWordList *[]string
// Changes all letters in each word to lower case
Downcase bool
// Changes all letters in each word to upper case
Upcase bool
// If present, this function is emitted on all words in the dictionary,
// if the provided function returns true, the word is not included in the
// word list.
ExcludeWord ExcludeWord
// Emittted on all words in the dictionary
TransformWord TransformWord
}
var DefaultDictionaryConfig = DictionaryConfig {
MinLength: 3,
MaxLength: 6,
}

type Dictionary interface {
GetRandomWord() string
GetListLength() int
GetWordList() []string
}

type babbleDictionary struct {
sourceList []string
config *DictionaryConfig
}
// NewDictionaryWithConfig creates a new dictionary with the supplied
// configuration struct.
// c = babble.DictionaryConfig {
// MinLength: 3,
// MaxLength: 5,
// Downcase: true,
//
// }
// d = NewDictionaryWithConfig(c)
func NewDictionaryWithConfig(c DictionaryConfig) Dictionary {
if c.Upcase && c.Downcase {
panic("cannot upcase and downcase the dictionary at the same time, invalid dictionary config")
}
d := &babbleDictionary{
config: &c,
sourceList: []string{},
}
if c.CustomWordList == nil {
d.load()
}else{
d.sourceList = *c.CustomWordList
if d.config.ExcludeWord != nil {
d.loadWithExclude()
} else {
newSource := []string{}
for _, s := range d.sourceList {
newSource = append(newSource, d.applyTransform(s))
}
d.sourceList = newSource
}
}
return d
}

// GetRandomWord returns a random word from the dictionary
func (d *babbleDictionary) GetRandomWord() string {
if d.config.MinLength > d.config.MaxLength {
panic("minimum length cannot exceed maximum length")
}
return getRandomWordFromList(d.config.MinLength, d.config.MaxLength,d.sourceList)
}

// GetListLength returns the length of the currently loaded word list.
func (d *babbleDictionary) GetListLength() int {
return len(d.sourceList)
}

// applyTransform applies the configured transformation function
// on each string, and if Upcase or Downcase is true, that
// transformation is applied
func (d *babbleDictionary) applyTransform(s string) (ts string) {
txf := d.config.TransformWord
if txf != nil {
ts = txf(s)
}else{
ts = s
}
if d.config.Downcase {
return strings.ToLower(ts)
}
if d.config.Upcase {
return strings.ToUpper(ts)
}
return ts
}

// GetWordList returns the entire list of possible words
func (d *babbleDictionary) GetWordList() []string {
return d.sourceList
}

// loadWithExclude loads the list of possible words, emitting
// the ExcludeWord function if present to filter candidate
// words.
func (d *babbleDictionary) loadWithExclude() {
exc := d.config.ExcludeWord
newSource := []string{}
for _, s := range d.sourceList{
if(!exc(s)){
newSource = append(newSource, d.applyTransform(s))
}
}
d.sourceList = newSource
}

// load loads the list of possible words
func (d *babbleDictionary) load() {
list := readAvailableDictionary()
d.sourceList = GenerateEligibleWordList(list, d.config.MinLength, d.config.MaxLength)
if d.config.ExcludeWord != nil {
d.loadWithExclude()
} else {
newSource := []string{}
for _, s := range d.sourceList {
newSource = append(newSource, d.applyTransform(s))
}
d.sourceList = newSource
}
}

Loading